<commit_before>package main

/*
#cgo LDFLAGS: -lX11
#include <X11/Xlib.h>
*/
import "C"

import (
	"fmt"
	"gopkg.in/yaml.v2"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"os/exec"
	"strconv"
	"strings"
	"time"

	"github.com/gotk3/gotk3/gtk"
)

type gobarConfig struct {
	Listen   string `yaml:"listen"`
	CssPath  string `yaml:"css_path"`
	Position struct {
		X int `yaml:"x"`
		Y int `yaml:"y"`
	} `yaml:"position"`
	BarSize struct {
		X int `yaml:"x"`
		Y int `yaml:"y"`
	} `yaml:"bar_size"`
	Actions map[string]struct {
		Command  string  `yaml:"command"`
		Value    string  `yaml:"value"`
		Label    string  `yaml:"label"`
		Duration string  `yaml:"duration"`
		Min      float64 `yaml:"min"`
		Max      float64 `yaml:"max"`
	} `yaml:"actions"`
}

func getLabelHandler(label *gtk.Label, bar *gtk.LevelBar, win *gtk.Window) func(http.ResponseWriter, *http.Request) {
	return func(w http.ResponseWriter, r *http.Request) {
		var err error
		min := 0.0
		max := 100.0
		level := 50.0
		duration, _ := time.ParseDuration("700ms")
		labelText := "label string xD"

		vars := r.URL.Query()
		r.Body.Close()

		if val, ok := vars["label"]; ok {
			labelText = val[0]
		}
		if val, ok := vars["min"]; ok {
			min, err = strconv.ParseFloat(val[0], 64)
			if err != nil {
				log.Println("Got a wrong min value", val, err)
			}
		}
		if val, ok := vars["max"]; ok {
			max, err = strconv.ParseFloat(val[0], 64)
			if err != nil {
				log.Println("Got a wrong max value", val, err)
			}
		}
		if val, ok := vars["level"]; ok {
			level, err = strconv.ParseFloat(val[0], 64)
			if err != nil {
				log.Println("Got a wrong level value", val, err)
			}
		}
		if val, ok := vars["duration"]; ok {
			duration, err = time.ParseDuration(val[0])
			if err != nil {
				log.Println("Got a wrong duration value", val, err)
			}
		}

		_, _ = w.Write([]byte("OK\n"))

		go func() {
			bar.SetMinValue(min)
			bar.SetMaxValue(max)
			bar.SetValue(level)
			label.SetLabel(labelText)

			win.ShowAll()

			time.Sleep(duration)

			win.Resize(10, 10)
			win.Hide()
		}()
	}
}

func main() {
	var config gobarConfig

	if len(os.Args) != 2 {
		log.Fatalln("Usage:", os.Args[0], "<configuration file>")
	}

	data, err := ioutil.ReadFile(os.Args[1])
	if err != nil {
		log.Fatalln("Error reading configuration file:", err)
	}

	if err := yaml.Unmarshal(data, &config); err != nil {
		log.Fatalln("Error parsing configuration file:", err)
	}

	C.XInitThreads()
	gtk.Init(nil)

	win, err := gtk.WindowNew(gtk.WINDOW_TOPLEVEL)
	if err != nil {
		log.Fatal("Unable to create window:", err)
	}
	win.Connect("destroy", func() {
		gtk.MainQuit()
	})

	grid, err := gtk.GridNew()
	if err != nil {
		log.Fatal("Unable to create grid:", err)
	}

	css, err := gtk.CssProviderNew()
	if err != nil {
		log.Fatal("Unable to create css provider:", err)
	}

	lb := label()
	bar := levelBar(config.BarSize.X, config.BarSize.Y)

	grid.SetOrientation(gtk.ORIENTATION_HORIZONTAL)
	grid.Add(bar)
	grid.Add(lb)

	css.LoadFromPath(config.CssPath)

	style_context, err := lb.GetStyleContext()
	if err != nil {
		log.Fatal("Unable to get label style context:", err)
	}
	style_context.AddProvider(css, gtk.STYLE_PROVIDER_PRIORITY_USER)

	win.SetWMClass("gobar", "gobar")
	win.SetTitle("gobar")
	win.Add(grid)
	win.SetAcceptFocus(false)
	win.Move(config.Position.X, config.Position.Y)

	http.HandleFunc("/api/v1/bar", getLabelHandler(lb, bar, win))

	for key, value := range config.Actions {
		key := key
		value := value
		http.HandleFunc("/api/v1/action/"+key, func(w http.ResponseWriter, r *http.Request) {
			r.Body.Close()
			err := exec.Command("sh", "-c", value.Command).Run()
			if err != nil {
				log.Println("Command:", value.Command, "error:", err)
				fmt.Fprintln(w, "error:", err)
				return
			}
			out, err := exec.Command("sh", "-c", value.Value).Output()
			if err != nil {
				log.Println("Command:", value.Command, "error:", err)
				fmt.Fprintln(w, "error:", err)
				return
			}
			val, err := strconv.ParseFloat(strings.TrimSpace(string(out)), 64)
			if err != nil {
				log.Println("Error parsing as float", string(out), "error:", err)
				fmt.Fprintln(w, "error:", err)
				return
			}
			duration, err := time.ParseDuration(value.Duration)
			if err != nil {
				log.Println("Error paring as duration", duration, "error:", err)
				fmt.Fprintln(w, "error:", err)
			}

			_, _ = w.Write([]byte("OK\n"))

			go func() {
				lb.SetLabel(value.Label)

				bar.SetMinValue(value.Min)
				bar.SetMaxValue(value.Max)
				bar.SetValue(val)

				win.ShowAll()

				time.Sleep(duration)

				win.Resize(10, 10)
				win.Hide()
			}()
		})
	}

	go gtk.Main()

	http.ListenAndServe(config.Listen, nil)
}

func label() *gtk.Label {
	label, err := gtk.LabelNew("xD")

	if err != nil {
		log.Fatal("Unable to create label:", err)
	}

	return label
}

func levelBar(x, y int) *gtk.LevelBar {
	lb, err := gtk.LevelBarNew()

	if err != nil {
		log.Fatal("Unable to create level bar:", err)
	}

	lb.SetSizeRequest(x, y)

	return lb
}
<commit_msg>We can have fancier return values.<commit_after>package main

/*
#cgo LDFLAGS: -lX11
#include <X11/Xlib.h>
*/
import "C"

import (
	"fmt"
	"gopkg.in/yaml.v2"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"os/exec"
	"strconv"
	"strings"
	"time"

	"github.com/gotk3/gotk3/gtk"
)

type gobarConfig struct {
	Listen   string `yaml:"listen"`
	CssPath  string `yaml:"css_path"`
	Position struct {
		X int `yaml:"x"`
		Y int `yaml:"y"`
	} `yaml:"position"`
	BarSize struct {
		X int `yaml:"x"`
		Y int `yaml:"y"`
	} `yaml:"bar_size"`
	Actions map[string]struct {
		Command  string  `yaml:"command"`
		Value    string  `yaml:"value"`
		Label    string  `yaml:"label"`
		Duration string  `yaml:"duration"`
		Min      float64 `yaml:"min"`
		Max      float64 `yaml:"max"`
	} `yaml:"actions"`
}

func getLabelHandler(label *gtk.Label, bar *gtk.LevelBar, win *gtk.Window) func(http.ResponseWriter, *http.Request) {
	return func(w http.ResponseWriter, r *http.Request) {
		var err error
		min := 0.0
		max := 100.0
		level := 50.0
		duration, _ := time.ParseDuration("700ms")
		labelText := "label string xD"

		vars := r.URL.Query()
		r.Body.Close()

		if val, ok := vars["label"]; ok {
			labelText = val[0]
		}
		if val, ok := vars["min"]; ok {
			min, err = strconv.ParseFloat(val[0], 64)
			if err != nil {
				log.Println("Got a wrong min value", val, err)
			}
		}
		if val, ok := vars["max"]; ok {
			max, err = strconv.ParseFloat(val[0], 64)
			if err != nil {
				log.Println("Got a wrong max value", val, err)
			}
		}
		if val, ok := vars["level"]; ok {
			level, err = strconv.ParseFloat(val[0], 64)
			if err != nil {
				log.Println("Got a wrong level value", val, err)
			}
		}
		if val, ok := vars["duration"]; ok {
			duration, err = time.ParseDuration(val[0])
			if err != nil {
				log.Println("Got a wrong duration value", val, err)
			}
		}

		_, _ = w.Write([]byte("OK\n"))

		go func() {
			bar.SetMinValue(min)
			bar.SetMaxValue(max)
			bar.SetValue(level)
			label.SetLabel(labelText)

			win.ShowAll()

			time.Sleep(duration)

			win.Resize(10, 10)
			win.Hide()
		}()
	}
}

func main() {
	var config gobarConfig

	if len(os.Args) != 2 {
		log.Fatalln("Usage:", os.Args[0], "<configuration file>")
	}

	data, err := ioutil.ReadFile(os.Args[1])
	if err != nil {
		log.Fatalln("Error reading configuration file:", err)
	}

	if err := yaml.Unmarshal(data, &config); err != nil {
		log.Fatalln("Error parsing configuration file:", err)
	}

	C.XInitThreads()
	gtk.Init(nil)

	win, err := gtk.WindowNew(gtk.WINDOW_TOPLEVEL)
	if err != nil {
		log.Fatal("Unable to create window:", err)
	}
	win.Connect("destroy", func() {
		gtk.MainQuit()
	})

	grid, err := gtk.GridNew()
	if err != nil {
		log.Fatal("Unable to create grid:", err)
	}

	css, err := gtk.CssProviderNew()
	if err != nil {
		log.Fatal("Unable to create css provider:", err)
	}

	lb := label()
	bar := levelBar(config.BarSize.X, config.BarSize.Y)

	grid.SetOrientation(gtk.ORIENTATION_HORIZONTAL)
	grid.Add(bar)
	grid.Add(lb)

	css.LoadFromPath(config.CssPath)

	style_context, err := lb.GetStyleContext()
	if err != nil {
		log.Fatal("Unable to get label style context:", err)
	}
	style_context.AddProvider(css, gtk.STYLE_PROVIDER_PRIORITY_USER)

	win.SetWMClass("gobar", "gobar")
	win.SetTitle("gobar")
	win.Add(grid)
	win.SetAcceptFocus(false)
	win.Move(config.Position.X, config.Position.Y)

	http.HandleFunc("/api/v1/bar", getLabelHandler(lb, bar, win))

	for key, value := range config.Actions {
		key := key
		value := value
		http.HandleFunc("/api/v1/action/"+key, func(w http.ResponseWriter, r *http.Request) {
			r.Body.Close()
			err := exec.Command("sh", "-c", value.Command).Run()
			if err != nil {
				log.Println("Command:", value.Command, "error:", err)
				fmt.Fprintln(w, "error:", err)
				return
			}
			out, err := exec.Command("sh", "-c", value.Value).Output()
			if err != nil {
				log.Println("Command:", value.Command, "error:", err)
				fmt.Fprintln(w, "error:", err)
				return
			}
			val, err := strconv.ParseFloat(strings.TrimSpace(string(out)), 64)
			if err != nil {
				log.Println("Error parsing as float", string(out), "error:", err)
				fmt.Fprintln(w, "error:", err)
				return
			}
			duration, err := time.ParseDuration(value.Duration)
			if err != nil {
				log.Println("Error paring as duration", duration, "error:", err)
				fmt.Fprintln(w, "error:", err)
			}

			fmt.Fprintln(w, "status: OK\nvalue:", val)

			go func() {
				lb.SetLabel(value.Label)

				bar.SetMinValue(value.Min)
				bar.SetMaxValue(value.Max)
				bar.SetValue(val)

				win.ShowAll()

				time.Sleep(duration)

				win.Resize(10, 10)
				win.Hide()
			}()
		})
	}

	go gtk.Main()

	http.ListenAndServe(config.Listen, nil)
}

func label() *gtk.Label {
	label, err := gtk.LabelNew("xD")

	if err != nil {
		log.Fatal("Unable to create label:", err)
	}

	return label
}

func levelBar(x, y int) *gtk.LevelBar {
	lb, err := gtk.LevelBarNew()

	if err != nil {
		log.Fatal("Unable to create level bar:", err)
	}

	lb.SetSizeRequest(x, y)

	return lb
}
<|endoftext|>


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

// godoc: Go Documentation Server

// Web server tree:
//
//	http://godoc/		main landing page
//	http://godoc/doc/	serve from $GOROOT/doc - spec, mem, tutorial, etc.
//	http://godoc/src/	serve files from $GOROOT/src; .go gets pretty-printed
//	http://godoc/cmd/	serve documentation about commands (TODO)
//	http://godoc/pkg/	serve documentation about packages
//				(idea is if you say import "compress/zlib", you go to
//				http://godoc/pkg/compress/zlib)
//
// Command-line interface:
//
//	godoc packagepath [name ...]
//
//	godoc compress/zlib
//		- prints doc for package compress/zlib
//	godoc crypto/block Cipher NewCMAC
//		- prints doc for Cipher and NewCMAC in package crypto/block

package main

import (
	"bytes"
	"flag"
	"fmt"
	"http"
	"io"
	"log"
	"os"
	"time"
)

var (
	// periodic sync
	syncCmd             = flag.String("sync", "", "sync command; disabled if empty")
	syncMin             = flag.Int("sync_minutes", 0, "sync interval in minutes; disabled if <= 0")
	syncDelay delayTime // actual sync delay in minutes; usually syncDelay == syncMin, but delay may back off exponentially

	// server control
	httpaddr = flag.String("http", "", "HTTP service address (e.g., ':6060')")

	// layout control
	html = flag.Bool("html", false, "print HTML in command-line mode")
)

func serveError(c *http.Conn, r *http.Request, relpath string, err os.Error) {
	contents := applyTemplate(errorHTML, "errorHTML", err) // err may contain an absolute path!
	servePage(c, "File "+relpath, "", contents)
}

func exec(c *http.Conn, args []string) (status int) {
	r, w, err := os.Pipe()
	if err != nil {
		log.Stderrf("os.Pipe(): %v\n", err)
		return 2
	}

	bin := args[0]
	fds := []*os.File{nil, w, w}
	if *verbose {
		log.Stderrf("executing %v", args)
	}
	pid, err := os.ForkExec(bin, args, os.Environ(), goroot, fds)
	defer r.Close()
	w.Close()
	if err != nil {
		log.Stderrf("os.ForkExec(%q): %v\n", bin, err)
		return 2
	}

	var buf bytes.Buffer
	io.Copy(&buf, r)
	wait, err := os.Wait(pid, 0)
	if err != nil {
		os.Stderr.Write(buf.Bytes())
		log.Stderrf("os.Wait(%d, 0): %v\n", pid, err)
		return 2
	}
	status = wait.ExitStatus()
	if !wait.Exited() || status > 1 {
		os.Stderr.Write(buf.Bytes())
		log.Stderrf("executing %v failed (exit status = %d)", args, status)
		return
	}

	if *verbose {
		os.Stderr.Write(buf.Bytes())
	}
	if c != nil {
		c.SetHeader("content-type", "text/plain; charset=utf-8")
		c.Write(buf.Bytes())
	}

	return
}

// Maximum directory depth, adjust as needed.
const maxDirDepth = 24

func dosync(c *http.Conn, r *http.Request) {
	args := []string{"/bin/sh", "-c", *syncCmd}
	switch exec(c, args) {
	case 0:
		// sync succeeded and some files have changed;
		// update package tree.
		// TODO(gri): The directory tree may be temporarily out-of-sync.
		//            Consider keeping separate time stamps so the web-
		//            page can indicate this discrepancy.
		fsTree.set(newDirectory(goroot, maxDirDepth))
		fallthrough
	case 1:
		// sync failed because no files changed;
		// don't change the package tree
		syncDelay.set(*syncMin) //  revert to regular sync schedule
	default:
		// sync failed because of an error - back off exponentially, but try at least once a day
		syncDelay.backoff(24 * 60)
	}
}

func usage() {
	fmt.Fprintf(os.Stderr,
		"usage: godoc package [name ...]\n"+
			"	godoc -http=:6060\n")
	flag.PrintDefaults()
	os.Exit(2)
}

func loggingHandler(h http.Handler) http.Handler {
	return http.HandlerFunc(func(c *http.Conn, req *http.Request) {
		log.Stderrf("%s\t%s", c.RemoteAddr, req.URL)
		h.ServeHTTP(c, req)
	})
}

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

	// Check usage: either server and no args, or command line and args
	if (*httpaddr != "") != (flag.NArg() == 0) {
		usage()
	}

	if *tabwidth < 0 {
		log.Exitf("negative tabwidth %d", *tabwidth)
	}

	initHandlers()
	readTemplates()

	if *httpaddr != "" {
		// HTTP server mode.
		var handler http.Handler = http.DefaultServeMux
		if *verbose {
			log.Stderrf("Go Documentation Server\n")
			log.Stderrf("address = %s\n", *httpaddr)
			log.Stderrf("goroot = %s\n", goroot)
			log.Stderrf("tabwidth = %d\n", *tabwidth)
			if !fsMap.IsEmpty() {
				log.Stderr("user-defined mapping:")
				fsMap.Fprint(os.Stderr)
			}
			handler = loggingHandler(handler)
		}

		registerPublicHandlers(http.DefaultServeMux)
		if *syncCmd != "" {
			http.Handle("/debug/sync", http.HandlerFunc(dosync))
		}

		// Initialize directory tree with corresponding timestamp.
		// Do it in two steps:
		// 1) set timestamp right away so that the indexer is kicked on
		fsTree.set(nil)
		// 2) compute initial directory tree in a goroutine so that launch is quick
		go func() { fsTree.set(newDirectory(goroot, maxDirDepth)) }()

		// Start sync goroutine, if enabled.
		if *syncCmd != "" && *syncMin > 0 {
			syncDelay.set(*syncMin) // initial sync delay
			go func() {
				for {
					dosync(nil, nil)
					delay, _ := syncDelay.get()
					if *verbose {
						log.Stderrf("next sync in %dmin", delay.(int))
					}
					time.Sleep(int64(delay.(int)) * 60e9)
				}
			}()
		}

		// Start indexing goroutine.
		go indexer()

		// The server may have been restarted; always wait 1sec to
		// give the forking server a chance to shut down and release
		// the http port.
		// TODO(gri): Do we still need this?
		time.Sleep(1e9)

		// Start http server.
		if err := http.ListenAndServe(*httpaddr, handler); err != nil {
			log.Exitf("ListenAndServe %s: %v", *httpaddr, err)
		}
		return
	}

	// Command line mode.
	if *html {
		packageText = packageHTML
	}

	info := pkgHandler.getPageInfo(flag.Arg(0), flag.Arg(0), true)

	if info.PDoc == nil && info.Dirs == nil {
		// try again, this time assume it's a command
		info = cmdHandler.getPageInfo(flag.Arg(0), flag.Arg(0), false)
	}

	if info.PDoc != nil && flag.NArg() > 1 {
		args := flag.Args()
		info.PDoc.Filter(args[1:])
	}

	if err := packageText.Execute(info, os.Stdout); err != nil {
		log.Stderrf("packageText.Execute: %s", err)
	}
}
<commit_msg>godoc: fix path resolution for command-line one more time (sigh...)<commit_after>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// godoc: Go Documentation Server

// Web server tree:
//
//	http://godoc/		main landing page
//	http://godoc/doc/	serve from $GOROOT/doc - spec, mem, tutorial, etc.
//	http://godoc/src/	serve files from $GOROOT/src; .go gets pretty-printed
//	http://godoc/cmd/	serve documentation about commands (TODO)
//	http://godoc/pkg/	serve documentation about packages
//				(idea is if you say import "compress/zlib", you go to
//				http://godoc/pkg/compress/zlib)
//
// Command-line interface:
//
//	godoc packagepath [name ...]
//
//	godoc compress/zlib
//		- prints doc for package compress/zlib
//	godoc crypto/block Cipher NewCMAC
//		- prints doc for Cipher and NewCMAC in package crypto/block

package main

import (
	"bytes"
	"flag"
	"fmt"
	"http"
	"io"
	"log"
	"os"
	pathutil "path"
	"time"
)

var (
	// periodic sync
	syncCmd             = flag.String("sync", "", "sync command; disabled if empty")
	syncMin             = flag.Int("sync_minutes", 0, "sync interval in minutes; disabled if <= 0")
	syncDelay delayTime // actual sync delay in minutes; usually syncDelay == syncMin, but delay may back off exponentially

	// server control
	httpaddr = flag.String("http", "", "HTTP service address (e.g., ':6060')")

	// layout control
	html = flag.Bool("html", false, "print HTML in command-line mode")
)

func serveError(c *http.Conn, r *http.Request, relpath string, err os.Error) {
	contents := applyTemplate(errorHTML, "errorHTML", err) // err may contain an absolute path!
	servePage(c, "File "+relpath, "", contents)
}

func exec(c *http.Conn, args []string) (status int) {
	r, w, err := os.Pipe()
	if err != nil {
		log.Stderrf("os.Pipe(): %v\n", err)
		return 2
	}

	bin := args[0]
	fds := []*os.File{nil, w, w}
	if *verbose {
		log.Stderrf("executing %v", args)
	}
	pid, err := os.ForkExec(bin, args, os.Environ(), goroot, fds)
	defer r.Close()
	w.Close()
	if err != nil {
		log.Stderrf("os.ForkExec(%q): %v\n", bin, err)
		return 2
	}

	var buf bytes.Buffer
	io.Copy(&buf, r)
	wait, err := os.Wait(pid, 0)
	if err != nil {
		os.Stderr.Write(buf.Bytes())
		log.Stderrf("os.Wait(%d, 0): %v\n", pid, err)
		return 2
	}
	status = wait.ExitStatus()
	if !wait.Exited() || status > 1 {
		os.Stderr.Write(buf.Bytes())
		log.Stderrf("executing %v failed (exit status = %d)", args, status)
		return
	}

	if *verbose {
		os.Stderr.Write(buf.Bytes())
	}
	if c != nil {
		c.SetHeader("content-type", "text/plain; charset=utf-8")
		c.Write(buf.Bytes())
	}

	return
}

// Maximum directory depth, adjust as needed.
const maxDirDepth = 24

func dosync(c *http.Conn, r *http.Request) {
	args := []string{"/bin/sh", "-c", *syncCmd}
	switch exec(c, args) {
	case 0:
		// sync succeeded and some files have changed;
		// update package tree.
		// TODO(gri): The directory tree may be temporarily out-of-sync.
		//            Consider keeping separate time stamps so the web-
		//            page can indicate this discrepancy.
		fsTree.set(newDirectory(goroot, maxDirDepth))
		fallthrough
	case 1:
		// sync failed because no files changed;
		// don't change the package tree
		syncDelay.set(*syncMin) //  revert to regular sync schedule
	default:
		// sync failed because of an error - back off exponentially, but try at least once a day
		syncDelay.backoff(24 * 60)
	}
}

func usage() {
	fmt.Fprintf(os.Stderr,
		"usage: godoc package [name ...]\n"+
			"	godoc -http=:6060\n")
	flag.PrintDefaults()
	os.Exit(2)
}

func loggingHandler(h http.Handler) http.Handler {
	return http.HandlerFunc(func(c *http.Conn, req *http.Request) {
		log.Stderrf("%s\t%s", c.RemoteAddr, req.URL)
		h.ServeHTTP(c, req)
	})
}

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

	// Check usage: either server and no args, or command line and args
	if (*httpaddr != "") != (flag.NArg() == 0) {
		usage()
	}

	if *tabwidth < 0 {
		log.Exitf("negative tabwidth %d", *tabwidth)
	}

	initHandlers()
	readTemplates()

	if *httpaddr != "" {
		// HTTP server mode.
		var handler http.Handler = http.DefaultServeMux
		if *verbose {
			log.Stderrf("Go Documentation Server\n")
			log.Stderrf("address = %s\n", *httpaddr)
			log.Stderrf("goroot = %s\n", goroot)
			log.Stderrf("tabwidth = %d\n", *tabwidth)
			if !fsMap.IsEmpty() {
				log.Stderr("user-defined mapping:")
				fsMap.Fprint(os.Stderr)
			}
			handler = loggingHandler(handler)
		}

		registerPublicHandlers(http.DefaultServeMux)
		if *syncCmd != "" {
			http.Handle("/debug/sync", http.HandlerFunc(dosync))
		}

		// Initialize directory tree with corresponding timestamp.
		// Do it in two steps:
		// 1) set timestamp right away so that the indexer is kicked on
		fsTree.set(nil)
		// 2) compute initial directory tree in a goroutine so that launch is quick
		go func() { fsTree.set(newDirectory(goroot, maxDirDepth)) }()

		// Start sync goroutine, if enabled.
		if *syncCmd != "" && *syncMin > 0 {
			syncDelay.set(*syncMin) // initial sync delay
			go func() {
				for {
					dosync(nil, nil)
					delay, _ := syncDelay.get()
					if *verbose {
						log.Stderrf("next sync in %dmin", delay.(int))
					}
					time.Sleep(int64(delay.(int)) * 60e9)
				}
			}()
		}

		// Start indexing goroutine.
		go indexer()

		// The server may have been restarted; always wait 1sec to
		// give the forking server a chance to shut down and release
		// the http port.
		// TODO(gri): Do we still need this?
		time.Sleep(1e9)

		// Start http server.
		if err := http.ListenAndServe(*httpaddr, handler); err != nil {
			log.Exitf("ListenAndServe %s: %v", *httpaddr, err)
		}
		return
	}

	// Command line mode.
	if *html {
		packageText = packageHTML
	}

	// determine paths
	path := flag.Arg(0)
	if len(path) > 0 && path[0] == '.' {
		// assume cwd; don't assume -goroot
		cwd, _ := os.Getwd() // ignore errors
		path = pathutil.Join(cwd, path)
	}
	relpath := path
	abspath := path
	if len(path) > 0 && path[0] != '/' {
		abspath = absolutePath(path, pkgHandler.fsRoot)
	} else {
		relpath = relativePath(path)
	}

	info := pkgHandler.getPageInfo(abspath, relpath, true)

	if info.PDoc == nil && info.Dirs == nil {
		// try again, this time assume it's a command
		if len(path) > 0 && path[0] != '/' {
			abspath = absolutePath(path, cmdHandler.fsRoot)
		}
		info = cmdHandler.getPageInfo(abspath, relpath, false)
	}

	if info.PDoc != nil && flag.NArg() > 1 {
		args := flag.Args()
		info.PDoc.Filter(args[1:])
	}

	if err := packageText.Execute(info, os.Stdout); err != nil {
		log.Stderrf("packageText.Execute: %s", err)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"go/token"
	"strings"
)

func checkGoDocs(lc <-chan *Lexeme, outc chan<- *CheckedLexeme) {
	tch := Filter(lc, DeclCommentFilter)
	for {
		ll := []*Lexeme{}
		for {
			l, ok := <-tch
			if !ok {
				return
			}
			if l.tok == token.ILLEGAL {
				break
			}
			ll = append(ll, l)
		}

		comm := beginGoDoc(ll)

		// does the comment line up with the next line?
		after := afterGoDoc(ll)
		if after.pos.Column != comm.pos.Column {
			continue
		}

		// does the comment have a token for documentation?
		fields := strings.Fields(comm.lit)
		if len(fields) < 2 {
			continue
		}

		// what token should the documentation match?
		cmplex := ll[len(ll)-1]
		if len(ll) >= 2 && ll[len(ll)-2].tok == token.IDENT {
			cmplex = ll[len(ll)-2]
		}
		if fields[1] == cmplex.lit {
			continue
		}

		// bad godoc
		cw := []CheckedWord{{fields[1], cmplex.lit}}
		cl := &CheckedLexeme{comm, "godoc", cw}
		outc <- cl
	}
}

// beginGoDoc gets the last comment block from a string of comments
func beginGoDoc(ll []*Lexeme) (comm *Lexeme) {
	wantLine := 0
	for _, l := range ll {
		if l.tok != token.COMMENT {
			break
		}
		if l.pos.Line != wantLine {
			comm = l
		}
		wantLine = l.pos.Line + 1
	}
	return comm
}

// afterGoDoc gets the first token following the comments
func afterGoDoc(ll []*Lexeme) *Lexeme {
	for _, l := range ll {
		if l.tok != token.COMMENT {
			return l
		}
	}
	return nil
}
<commit_msg>godoc: label local / exported identifiers<commit_after>package main

import (
	"go/token"
	"strings"
)

func checkGoDocs(lc <-chan *Lexeme, outc chan<- *CheckedLexeme) {
	tch := Filter(lc, DeclCommentFilter)
	for {
		ll := []*Lexeme{}
		for {
			l, ok := <-tch
			if !ok {
				return
			}
			if l.tok == token.ILLEGAL {
				break
			}
			ll = append(ll, l)
		}

		godoc := beginGoDoc(ll)

		// does the comment line up with the next line?
		after := afterGoDoc(ll)
		if after.pos.Column != godoc.pos.Column {
			continue
		}

		// does the comment have a token for documentation?
		fields := strings.Fields(godoc.lit)
		if len(fields) < 2 {
			continue
		}

		// what token should the documentation match?
		cmplex := ll[len(ll)-1]
		if len(ll) >= 2 && ll[len(ll)-2].tok == token.IDENT {
			cmplex = ll[len(ll)-2]
		}
		if fields[1] == cmplex.lit {
			continue
		}

		// bad godoc
		label := "godoc-local"
		if strings.ToUpper(cmplex.lit)[0] == cmplex.lit[0] {
			label = "godoc-export"
		}
		cw := []CheckedWord{{fields[1], cmplex.lit}}
		cl := &CheckedLexeme{godoc, label, cw}
		outc <- cl
	}
}

// beginGoDoc gets the last comment block from a string of comments
func beginGoDoc(ll []*Lexeme) (comm *Lexeme) {
	wantLine := 0
	for _, l := range ll {
		if l.tok != token.COMMENT {
			break
		}
		if l.pos.Line != wantLine {
			comm = l
		}
		wantLine = l.pos.Line + 1
	}
	return comm
}

// afterGoDoc gets the first token following the comments
func afterGoDoc(ll []*Lexeme) *Lexeme {
	for _, l := range ll {
		if l.tok != token.COMMENT {
			return l
		}
	}
	return nil
}
<|endoftext|>


<commit_before><commit_msg>And copy the database stuff into the main test file<commit_after><|endoftext|>


<commit_before>package gorai

import (
	"github.com/facebookgo/grace/gracehttp"
	"github.com/go51/auth551"
	"github.com/go51/container551"
	"github.com/go51/cookie551"
	"github.com/go51/log551"
	"github.com/go51/memcache551"
	"github.com/go51/model551"
	"github.com/go51/mysql551"
	"github.com/go51/response551"
	"github.com/go51/router551"
	"github.com/go51/secure551"
	"net/http"
	"time"
)

type gorai struct {
	config       *Config
	logger       *log551.Log551
	router       *router551.Router
	modelManager *model551.Model
	auth         *auth551.Auth
}

var goraiInstance *gorai = nil

func Load(appConfig ...interface{}) *gorai {
	if goraiInstance != nil {
		return goraiInstance
	}

	goraiInstance = &gorai{}

	goraiInstance.initialize(appConfig[0])

	return goraiInstance
}

func (g *gorai) initialize(appConfig interface{}) {
	// load config
	g.config = loadConfig(appConfig)

	// Logger
	g.logger = log551.New(&g.config.Framework.SystemLog)
	g.logger.Open()
	defer g.logger.Close()

	g.logger.Information("--[ initialize gorai - START ]--")
	g.logger.Information("Success! [Log551]")

	// Router
	g.router = router551.Load()
	g.logger.Information("Success! [Router551]")

	// ModelManager
	g.modelManager = model551.Load()
	g.logger.Information("Success! [Model551]")

	// Add Auth Model
	g.modelManager.Add(auth551.NewUserModel, auth551.NewUserModelPointer)
	g.modelManager.Add(auth551.NewUserTokenModel, auth551.NewUserTokenModelPointer)
	g.logger.Information("Success! [Add auth models]")

	// Auth
	g.auth = auth551.Load(g.config.Framework.Auth)
	g.logger.Information("Success! [Auth551]")

	g.logger.Information("--[ initialize gorai - END   ]--")
}

func (g *gorai) Run() {
	server := &http.Server{
		Addr:         g.config.Framework.WebServer.Host + ":" + g.config.Framework.WebServer.Port,
		Handler:      webHandler(),
		ReadTimeout:  g.config.Framework.WebServer.ReadTimeout * time.Second,
		WriteTimeout: g.config.Framework.WebServer.WriteTimeout * time.Second,
	}
	gracehttp.Serve(server)

	g.logger.Close()
}

func webHandler() http.Handler {
	mux := http.NewServeMux()

	mux.HandleFunc("/static/", staticResource)
	mux.HandleFunc("/", rootFunc)

	return mux
}

func staticResource(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Cache-Control-Max-Age", "10")
	http.ServeFile(w, r, r.URL.Path[1:])

}

func rootFunc(w http.ResponseWriter, r *http.Request) {

	g := Load()

	l := log551.New(&g.config.Framework.SystemLog)
	l.Open()
	defer l.Close()

	mysql := mysql551.New(&g.config.Framework.Database)

	cookie := cookie551.New(w, r)

	sid := g.sid(cookie)
	sidShort := sid[:10]
	l.Debugf("%s SID: %s", sidShort, sid)

	session := memcache551.New(&g.config.Framework.Session.Server, sid)

	route := g.router.FindRouteByPathMatch(r.Method, r.URL.Path)

	var data interface{} = nil
	if route != nil {
		l.Debugf("%s --[ Routing ]--", sidShort)
		l.Debugf("%s Path: %s", sidShort, r.URL.Path)
		l.Debugf("%s Neme: %s", sidShort, route.Name())
		c := container551.New()
		c.SetSID(sid)
		c.SetResponseWriter(w)
		c.SetRequest(r)
		c.SetLogger(l)
		c.SetLogger(l)
		c.SetCookie(cookie)
		c.SetDb(mysql)
		c.SetSession(session)
		c.SetModel(g.modelManager)
		c.SetAuth(g.auth)

		action := route.Action()
		data = action(c)
		response551.Response(w, r, data, route.PackageName(), route.Name())
	} else {
		l.Errorf("%s --[ Routing ]--", sidShort)
		l.Errorf("%s Path: %s", sidShort, r.URL.Path)
		l.Errorf("%s Neme: Route not found.", sidShort)
		data = response551.Error(404, "Route not found.")
		response551.Response(w, r, data, "", "")
	}

}

func (g *gorai) Config() *Config {
	return g.config
}

func (g *gorai) Logger() *log551.Log551 {
	return g.logger
}

func (g *gorai) Router() *router551.Router {
	return g.router
}

func (g *gorai) sid(cookie *cookie551.Cookie) string {
	sid, err := cookie.Get(g.config.Framework.Session.CookieKeyName)
	if err == nil {
		return sid
	}

	sid = secure551.Hash()

	cookie.Set(g.config.Framework.Session.CookieKeyName, sid, 60*60*24*365)

	return sid

}
<commit_msg>refs #30 起動時に auth551 インスタンスを保持して、リクエスト時に containe551 に保持する<commit_after>package gorai

import (
	"github.com/facebookgo/grace/gracehttp"
	"github.com/go51/auth551"
	"github.com/go51/container551"
	"github.com/go51/cookie551"
	"github.com/go51/log551"
	"github.com/go51/memcache551"
	"github.com/go51/model551"
	"github.com/go51/mysql551"
	"github.com/go51/response551"
	"github.com/go51/router551"
	"github.com/go51/secure551"
	"net/http"
	"time"
)

type gorai struct {
	config       *Config
	logger       *log551.Log551
	router       *router551.Router
	modelManager *model551.Model
	auth         *auth551.Auth
}

var goraiInstance *gorai = nil

func Load(appConfig ...interface{}) *gorai {
	if goraiInstance != nil {
		return goraiInstance
	}

	goraiInstance = &gorai{}

	goraiInstance.initialize(appConfig[0])

	return goraiInstance
}

func (g *gorai) initialize(appConfig interface{}) {
	// load config
	g.config = loadConfig(appConfig)

	// Logger
	g.logger = log551.New(&g.config.Framework.SystemLog)
	g.logger.Open()
	defer g.logger.Close()

	g.logger.Information("--[ initialize gorai - START ]--")
	g.logger.Information("Success! [Log551]")

	// Router
	g.router = router551.Load()
	g.logger.Information("Success! [Router551]")

	// ModelManager
	g.modelManager = model551.Load()
	g.logger.Information("Success! [Model551]")

	// Add Auth Model
	g.modelManager.Add(auth551.NewUserModel, auth551.NewUserModelPointer)
	g.modelManager.Add(auth551.NewUserTokenModel, auth551.NewUserTokenModelPointer)
	g.logger.Information("Success! [Add auth models]")

	// Auth
	g.auth = auth551.Load(&g.config.Framework.Auth)
	g.logger.Information("Success! [Auth551]")

	g.logger.Information("--[ initialize gorai - END   ]--")
}

func (g *gorai) Run() {
	server := &http.Server{
		Addr:         g.config.Framework.WebServer.Host + ":" + g.config.Framework.WebServer.Port,
		Handler:      webHandler(),
		ReadTimeout:  g.config.Framework.WebServer.ReadTimeout * time.Second,
		WriteTimeout: g.config.Framework.WebServer.WriteTimeout * time.Second,
	}
	gracehttp.Serve(server)

	g.logger.Close()
}

func webHandler() http.Handler {
	mux := http.NewServeMux()

	mux.HandleFunc("/static/", staticResource)
	mux.HandleFunc("/", rootFunc)

	return mux
}

func staticResource(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Cache-Control-Max-Age", "10")
	http.ServeFile(w, r, r.URL.Path[1:])

}

func rootFunc(w http.ResponseWriter, r *http.Request) {

	g := Load()

	l := log551.New(&g.config.Framework.SystemLog)
	l.Open()
	defer l.Close()

	mysql := mysql551.New(&g.config.Framework.Database)

	cookie := cookie551.New(w, r)

	sid := g.sid(cookie)
	sidShort := sid[:10]
	l.Debugf("%s SID: %s", sidShort, sid)

	session := memcache551.New(&g.config.Framework.Session.Server, sid)

	route := g.router.FindRouteByPathMatch(r.Method, r.URL.Path)

	var data interface{} = nil
	if route != nil {
		l.Debugf("%s --[ Routing ]--", sidShort)
		l.Debugf("%s Path: %s", sidShort, r.URL.Path)
		l.Debugf("%s Neme: %s", sidShort, route.Name())
		c := container551.New()
		c.SetSID(sid)
		c.SetResponseWriter(w)
		c.SetRequest(r)
		c.SetLogger(l)
		c.SetLogger(l)
		c.SetCookie(cookie)
		c.SetDb(mysql)
		c.SetSession(session)
		c.SetModel(g.modelManager)
		c.SetAuth(g.auth)

		action := route.Action()
		data = action(c)
		response551.Response(w, r, data, route.PackageName(), route.Name())
	} else {
		l.Errorf("%s --[ Routing ]--", sidShort)
		l.Errorf("%s Path: %s", sidShort, r.URL.Path)
		l.Errorf("%s Neme: Route not found.", sidShort)
		data = response551.Error(404, "Route not found.")
		response551.Response(w, r, data, "", "")
	}

}

func (g *gorai) Config() *Config {
	return g.config
}

func (g *gorai) Logger() *log551.Log551 {
	return g.logger
}

func (g *gorai) Router() *router551.Router {
	return g.router
}

func (g *gorai) sid(cookie *cookie551.Cookie) string {
	sid, err := cookie.Get(g.config.Framework.Session.CookieKeyName)
	if err == nil {
		return sid
	}

	sid = secure551.Hash()

	cookie.Set(g.config.Framework.Session.CookieKeyName, sid, 60*60*24*365)

	return sid

}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"go/build"
	"io"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"strings"

	"code.google.com/p/go.tools/go/loader"
	"code.google.com/p/go.tools/godoc/vfs"

	"sourcegraph.com/sourcegraph/srclib-go/gog"
	"sourcegraph.com/sourcegraph/srclib-go/gog/definfo"
	defpkg "sourcegraph.com/sourcegraph/srclib-go/golang_def"
	"sourcegraph.com/sourcegraph/srclib/graph"
	"sourcegraph.com/sourcegraph/srclib/grapher"
	"sourcegraph.com/sourcegraph/srclib/repo"
	"sourcegraph.com/sourcegraph/srclib/unit"
)

func init() {
	_, err := parser.AddCommand("graph",
		"graph a Go package",
		"Graph a Go package, producing all defs, refs, and docs.",
		&graphCmd,
	)
	if err != nil {
		log.Fatal(err)
	}

	// Check that we have the '-i' flag.
	cmd := exec.Command("go", "help", "build")
	o, err := cmd.Output()
	if err != nil {
		log.Fatal(err)
	}
	usage := strings.Split(string(o), "\n")[0] // The usage is on the first line.
	matched, err := regexp.MatchString("-i", usage)
	if err != nil {
		log.Fatal(err)
	}
	if !matched {
		log.Fatal("'go build' does not have the '-i' flag. Please upgrade to go1.3+.")
	}
}

type GraphCmd struct{}

var graphCmd GraphCmd

func (c *GraphCmd) Execute(args []string) error {
	var unit *unit.SourceUnit
	if err := json.NewDecoder(os.Stdin).Decode(&unit); err != nil {
		return err
	}
	if err := os.Stdin.Close(); err != nil {
		return err
	}

	if err := unmarshalTypedConfig(unit.Config); err != nil {
		return err
	}
	if err := config.apply(); err != nil {
		return err
	}

	if os.Getenv("IN_DOCKER_CONTAINER") != "" {
		buildPkg, err := UnitDataAsBuildPackage(unit)
		if err != nil {
			return err
		}

		// Make a new GOPATH.
		buildContext.GOPATH = "/tmp/gopath"

		// Set up GOPATH so it has this repo.
		log.Printf("Setting up a new GOPATH at %s", buildContext.GOPATH)
		dir := filepath.Join(buildContext.GOPATH, "src", string(unit.Repo))
		if err := os.MkdirAll(filepath.Dir(dir), 0700); err != nil {
			return err
		}
		log.Printf("Creating symlink to oldname %q at newname %q.", cwd, dir)
		if err := os.Symlink(cwd, dir); err != nil {
			return err
		}

		log.Printf("Changing directory to %q.", dir)
		if err := os.Chdir(dir); err != nil {
			return err
		}
		dockerCWD = cwd

		if config.GOROOT == "" {
			cwd = dir
		}

		// Get and install deps. (Only deps not in this repo; if we call `go
		// get` on this repo, we will either try to check out a different
		// version or fail with 'stale checkout?' because the .dockerignore
		// doesn't copy the .git dir.)
		var externalDeps []string
		for _, dep := range unit.Dependencies {
			importPath := dep.(string)
			if !strings.HasPrefix(importPath, string(unit.Repo)) && importPath != "C" {
				externalDeps = append(externalDeps, importPath)
			}
		}
		cmd := exec.Command("go", "get", "-d", "-t", "-v", "./"+buildPkg.Dir)
		cmd.Args = append(cmd.Args, externalDeps...)
		cmd.Env = config.env()
		cmd.Stdout, cmd.Stderr = os.Stderr, os.Stderr
		log.Printf("Downloading import dependencies: %v (env vars: %v).", cmd.Args, cmd.Env)
		if err := cmd.Run(); err != nil {
			return err
		}
		log.Printf("Finished downloading dependencies.")
	}

	out, err := Graph(unit)
	if err != nil {
		return err
	}

	// Make paths relative to repo.
	for _, gs := range out.Defs {
		if gs.File == "" {
			log.Printf("no file %+v", gs)
		}
		if gs.File != "" {
			gs.File = relPath(cwd, gs.File)
		}
	}
	for _, gr := range out.Refs {
		if gr.File != "" {
			gr.File = relPath(cwd, gr.File)
		}
	}
	for _, gd := range out.Docs {
		if gd.File != "" {
			gd.File = relPath(cwd, gd.File)
		}
	}

	if err := json.NewEncoder(os.Stdout).Encode(out); err != nil {
		return err
	}
	return nil
}

func relPath(base, path string) string {
	rp, err := filepath.Rel(base, path)
	if err != nil {
		log.Fatalf("Failed to make path %q relative to %q: %s", path, base, err)
	}

	// TODO(sqs): hack
	if strings.HasPrefix(rp, "../../../") && dockerCWD != "" {
		rp, err = filepath.Rel(dockerCWD, path)
		if err != nil {
			log.Fatalf("Failed to make path %q relative to %q: %s", path, cwd, err)
		}
	}

	return rp
}

func Graph(unit *unit.SourceUnit) (*grapher.Output, error) {
	pkg, err := UnitDataAsBuildPackage(unit)
	if err != nil {
		return nil, err
	}

	o, err := doGraph(pkg)
	if err != nil {
		return nil, err
	}

	o2 := grapher.Output{}

	uri := string(unit.Repo)

	for _, gs := range o.Defs {
		d, err := convertGoDef(gs, uri)
		if err != nil {
			return nil, err
		}
		if d != nil {
			o2.Defs = append(o2.Defs, d)
		}
	}
	for _, gr := range o.Refs {
		r, err := convertGoRef(gr, uri)
		if err != nil {
			return nil, err
		}
		if r != nil {
			o2.Refs = append(o2.Refs, r)
		}
	}
	for _, gd := range o.Docs {
		d, err := convertGoDoc(gd, uri)
		if err != nil {
			return nil, err
		}
		if d != nil {
			o2.Docs = append(o2.Docs, d)
		}
	}

	return &o2, nil
}

func convertGoDef(gs *gog.Def, repoURI string) (*graph.Def, error) {
	resolvedTarget, err := ResolveDep(gs.DefKey.PackageImportPath, repoURI)
	if err != nil {
		return nil, err
	}
	path := graph.DefPath(pathOrDot(strings.Join(gs.Path, "/")))
	treePath := treePath(string(path))
	if !treePath.IsValid() {
		return nil, fmt.Errorf("'%s' is not a valid tree-path", treePath)
	}

	def := &graph.Def{
		DefKey: graph.DefKey{
			Unit:     resolvedTarget.ToUnit,
			UnitType: resolvedTarget.ToUnitType,
			Path:     path,
		},
		TreePath: treePath,

		Name: gs.Name,
		Kind: definfo.GeneralKindMap[gs.Kind],

		File:     gs.File,
		DefStart: gs.DeclSpan[0],
		DefEnd:   gs.DeclSpan[1],

		Exported: gs.DefInfo.Exported,
		Test:     strings.HasSuffix(gs.File, "_test.go"),
	}

	d := defpkg.DefData{
		PackageImportPath: gs.DefKey.PackageImportPath,
		DefInfo:           gs.DefInfo,
	}
	def.Data, err = json.Marshal(d)
	if err != nil {
		return nil, err
	}

	if def.File == "" {
		// some cgo defs have empty File; omit them
		return nil, nil
	}

	return def, nil
}

func convertGoRef(gr *gog.Ref, repoURI string) (*graph.Ref, error) {
	resolvedTarget, err := ResolveDep(gr.Def.PackageImportPath, repoURI)
	if err != nil {
		return nil, err
	}
	if resolvedTarget == nil {
		return nil, nil
	}

	return &graph.Ref{
		DefRepo:     uriOrEmpty(resolvedTarget.ToRepoCloneURL),
		DefPath:     graph.DefPath(pathOrDot(strings.Join(gr.Def.Path, "/"))),
		DefUnit:     resolvedTarget.ToUnit,
		DefUnitType: resolvedTarget.ToUnitType,
		Def:         gr.IsDef,
		File:        gr.File,
		Start:       gr.Span[0],
		End:         gr.Span[1],
	}, nil
}

func convertGoDoc(gd *gog.Doc, repoURI string) (*graph.Doc, error) {
	resolvedTarget, err := ResolveDep(gd.PackageImportPath, repoURI)
	if err != nil {
		return nil, err
	}
	return &graph.Doc{
		DefKey: graph.DefKey{
			Path:     graph.DefPath(pathOrDot(strings.Join(gd.Path, "/"))),
			Unit:     resolvedTarget.ToUnit,
			UnitType: resolvedTarget.ToUnitType,
		},
		Format: gd.Format,
		Data:   gd.Data,
		File:   gd.File,
		Start:  gd.Span[0],
		End:    gd.Span[1],
	}, nil
}

func uriOrEmpty(cloneURL string) repo.URI {
	if cloneURL == "" {
		return ""
	}
	return repo.MakeURI(cloneURL)
}

func pathOrDot(path string) string {
	if path == "" {
		return "."
	}
	return path
}

func treePath(path string) graph.TreePath {
	if path == "" || path == "." {
		return graph.TreePath(".")
	}
	return graph.TreePath(fmt.Sprintf("./%s", path))
}

func doGraph(pkg *build.Package) (*gog.Output, error) {
	importPath := pkg.ImportPath

	// If we've overridden GOROOT and we're building a package not in
	// $GOROOT/src/pkg (such as "cmd/go"), then we need to virtualize GOROOT
	// because we can't set GOPATH=GOROOT (go/build ignores GOPATH in that
	// case).
	if config.GOROOT != "" && strings.HasPrefix(importPath, "cmd/") {
		// Unset our custom GOROOT (since we're routing FS ops to it using
		// vfs) and set it as our GOPATH.
		buildContext.GOROOT = build.Default.GOROOT
		buildContext.GOPATH = config.GOROOT

		virtualCWD = build.Default.GOROOT

		ns := vfs.NameSpace{}
		ns.Bind(filepath.Join(buildContext.GOROOT, "src/pkg"), vfs.OS(filepath.Join(config.GOROOT, "src/pkg")), "/", vfs.BindBefore)
		ns.Bind("/", vfs.OS("/"), "/", vfs.BindAfter)
		buildContext.IsDir = func(path string) bool {
			fi, err := ns.Stat(path)
			return err == nil && fi.Mode().IsDir()
		}
		buildContext.HasSubdir = func(root, dir string) (rel string, ok bool) { panic("unexpected") }
		buildContext.OpenFile = func(path string) (io.ReadCloser, error) {
			f, err := ns.Open(path)
			return f, err
		}
		buildContext.ReadDir = ns.ReadDir
	}

	if !loaderConfig.SourceImports {
		tmpfile, err := ioutil.TempFile("", filepath.Base(importPath))
		if err != nil {
			return nil, err
		}

		// Install pkg.
		cmd := exec.Command("go", "build", "-o", tmpfile.Name(), "-i", "-v", importPath)
		cmd.Env = config.env()
		cmd.Stdout, cmd.Stderr = os.Stderr, os.Stderr
		log.Printf("Install %q: %v (env vars: %v)", importPath, cmd.Args, cmd.Env)
		if err := cmd.Run(); err != nil {
			return nil, err
		}
		if err := tmpfile.Close(); err != nil {
			return nil, err
		}
		if err := os.Remove(tmpfile.Name()); err != nil {
			return nil, err
		}
	}

	importUnsafe := importPath == "unsafe"

	// Special-case: if this is a Cgo package, treat the CgoFiles as GoFiles or
	// else the character offsets will be junk.
	//
	// See https://codereview.appspot.com/86140043.
	loaderConfig.Build.CgoEnabled = false
	build.Default = *loaderConfig.Build
	if len(pkg.CgoFiles) > 0 {
		var allGoFiles []string
		allGoFiles = append(allGoFiles, pkg.GoFiles...)
		allGoFiles = append(allGoFiles, pkg.CgoFiles...)
		allGoFiles = append(allGoFiles, pkg.TestGoFiles...)
		for i, f := range allGoFiles {
			allGoFiles[i] = filepath.Join(cwd, pkg.Dir, f)
		}
		if err := loaderConfig.CreateFromFilenames(pkg.ImportPath, allGoFiles...); err != nil {
			return nil, err
		}
	} else {
		// Normal import
		if err := loaderConfig.ImportWithTests(importPath); err != nil {
			return nil, err
		}
	}

	if importUnsafe {
		// Special-case "unsafe" because go/loader does not let you load it
		// directly.
		if loaderConfig.ImportPkgs == nil {
			loaderConfig.ImportPkgs = make(map[string]bool)
		}
		loaderConfig.ImportPkgs["unsafe"] = true
	}

	prog, err := loaderConfig.Load()
	if err != nil {
		return nil, err
	}

	g := gog.New(prog)

	var pkgs []*loader.PackageInfo
	for _, pkg := range prog.Created {
		if strings.HasSuffix(pkg.Pkg.Name(), "_test") {
			// ignore xtest packages
			continue
		}
		pkgs = append(pkgs, pkg)
	}
	for _, pkg := range prog.Imported {
		pkgs = append(pkgs, pkg)
	}

	for _, pkg := range pkgs {
		if err := g.Graph(pkg); err != nil {
			return nil, err
		}
	}

	return &g.Output, nil
}
<commit_msg>install binary pkgs (previously, go build -o flag meant that -i flag was not actually installing imported pkgs)<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"go/build"
	"io"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"strings"

	"code.google.com/p/go.tools/go/loader"
	"code.google.com/p/go.tools/godoc/vfs"

	"sourcegraph.com/sourcegraph/srclib-go/gog"
	"sourcegraph.com/sourcegraph/srclib-go/gog/definfo"
	defpkg "sourcegraph.com/sourcegraph/srclib-go/golang_def"
	"sourcegraph.com/sourcegraph/srclib/graph"
	"sourcegraph.com/sourcegraph/srclib/grapher"
	"sourcegraph.com/sourcegraph/srclib/repo"
	"sourcegraph.com/sourcegraph/srclib/unit"
)

func init() {
	_, err := parser.AddCommand("graph",
		"graph a Go package",
		"Graph a Go package, producing all defs, refs, and docs.",
		&graphCmd,
	)
	if err != nil {
		log.Fatal(err)
	}

	// Check that we have the '-i' flag.
	cmd := exec.Command("go", "help", "build")
	o, err := cmd.Output()
	if err != nil {
		log.Fatal(err)
	}
	usage := strings.Split(string(o), "\n")[0] // The usage is on the first line.
	matched, err := regexp.MatchString("-i", usage)
	if err != nil {
		log.Fatal(err)
	}
	if !matched {
		log.Fatal("'go build' does not have the '-i' flag. Please upgrade to go1.3+.")
	}
}

type GraphCmd struct{}

var graphCmd GraphCmd

func (c *GraphCmd) Execute(args []string) error {
	var unit *unit.SourceUnit
	if err := json.NewDecoder(os.Stdin).Decode(&unit); err != nil {
		return err
	}
	if err := os.Stdin.Close(); err != nil {
		return err
	}

	if err := unmarshalTypedConfig(unit.Config); err != nil {
		return err
	}
	if err := config.apply(); err != nil {
		return err
	}

	if os.Getenv("IN_DOCKER_CONTAINER") != "" {
		buildPkg, err := UnitDataAsBuildPackage(unit)
		if err != nil {
			return err
		}

		// Make a new GOPATH.
		buildContext.GOPATH = "/tmp/gopath"

		// Set up GOPATH so it has this repo.
		log.Printf("Setting up a new GOPATH at %s", buildContext.GOPATH)
		dir := filepath.Join(buildContext.GOPATH, "src", string(unit.Repo))
		if err := os.MkdirAll(filepath.Dir(dir), 0700); err != nil {
			return err
		}
		log.Printf("Creating symlink to oldname %q at newname %q.", cwd, dir)
		if err := os.Symlink(cwd, dir); err != nil {
			return err
		}

		log.Printf("Changing directory to %q.", dir)
		if err := os.Chdir(dir); err != nil {
			return err
		}
		dockerCWD = cwd

		if config.GOROOT == "" {
			cwd = dir
		}

		// Get and install deps. (Only deps not in this repo; if we call `go
		// get` on this repo, we will either try to check out a different
		// version or fail with 'stale checkout?' because the .dockerignore
		// doesn't copy the .git dir.)
		var externalDeps []string
		for _, dep := range unit.Dependencies {
			importPath := dep.(string)
			if !strings.HasPrefix(importPath, string(unit.Repo)) && importPath != "C" {
				externalDeps = append(externalDeps, importPath)
			}
		}
		cmd := exec.Command("go", "get", "-d", "-t", "-v", "./"+buildPkg.Dir)
		cmd.Args = append(cmd.Args, externalDeps...)
		cmd.Env = config.env()
		cmd.Stdout, cmd.Stderr = os.Stderr, os.Stderr
		log.Printf("Downloading import dependencies: %v (env vars: %v).", cmd.Args, cmd.Env)
		if err := cmd.Run(); err != nil {
			return err
		}
		log.Printf("Finished downloading dependencies.")
	}

	out, err := Graph(unit)
	if err != nil {
		return err
	}

	// Make paths relative to repo.
	for _, gs := range out.Defs {
		if gs.File == "" {
			log.Printf("no file %+v", gs)
		}
		if gs.File != "" {
			gs.File = relPath(cwd, gs.File)
		}
	}
	for _, gr := range out.Refs {
		if gr.File != "" {
			gr.File = relPath(cwd, gr.File)
		}
	}
	for _, gd := range out.Docs {
		if gd.File != "" {
			gd.File = relPath(cwd, gd.File)
		}
	}

	if err := json.NewEncoder(os.Stdout).Encode(out); err != nil {
		return err
	}
	return nil
}

func relPath(base, path string) string {
	rp, err := filepath.Rel(base, path)
	if err != nil {
		log.Fatalf("Failed to make path %q relative to %q: %s", path, base, err)
	}

	// TODO(sqs): hack
	if strings.HasPrefix(rp, "../../../") && dockerCWD != "" {
		rp, err = filepath.Rel(dockerCWD, path)
		if err != nil {
			log.Fatalf("Failed to make path %q relative to %q: %s", path, cwd, err)
		}
	}

	return rp
}

func Graph(unit *unit.SourceUnit) (*grapher.Output, error) {
	pkg, err := UnitDataAsBuildPackage(unit)
	if err != nil {
		return nil, err
	}

	o, err := doGraph(pkg)
	if err != nil {
		return nil, err
	}

	o2 := grapher.Output{}

	uri := string(unit.Repo)

	for _, gs := range o.Defs {
		d, err := convertGoDef(gs, uri)
		if err != nil {
			return nil, err
		}
		if d != nil {
			o2.Defs = append(o2.Defs, d)
		}
	}
	for _, gr := range o.Refs {
		r, err := convertGoRef(gr, uri)
		if err != nil {
			return nil, err
		}
		if r != nil {
			o2.Refs = append(o2.Refs, r)
		}
	}
	for _, gd := range o.Docs {
		d, err := convertGoDoc(gd, uri)
		if err != nil {
			return nil, err
		}
		if d != nil {
			o2.Docs = append(o2.Docs, d)
		}
	}

	return &o2, nil
}

func convertGoDef(gs *gog.Def, repoURI string) (*graph.Def, error) {
	resolvedTarget, err := ResolveDep(gs.DefKey.PackageImportPath, repoURI)
	if err != nil {
		return nil, err
	}
	path := graph.DefPath(pathOrDot(strings.Join(gs.Path, "/")))
	treePath := treePath(string(path))
	if !treePath.IsValid() {
		return nil, fmt.Errorf("'%s' is not a valid tree-path", treePath)
	}

	def := &graph.Def{
		DefKey: graph.DefKey{
			Unit:     resolvedTarget.ToUnit,
			UnitType: resolvedTarget.ToUnitType,
			Path:     path,
		},
		TreePath: treePath,

		Name: gs.Name,
		Kind: definfo.GeneralKindMap[gs.Kind],

		File:     gs.File,
		DefStart: gs.DeclSpan[0],
		DefEnd:   gs.DeclSpan[1],

		Exported: gs.DefInfo.Exported,
		Test:     strings.HasSuffix(gs.File, "_test.go"),
	}

	d := defpkg.DefData{
		PackageImportPath: gs.DefKey.PackageImportPath,
		DefInfo:           gs.DefInfo,
	}
	def.Data, err = json.Marshal(d)
	if err != nil {
		return nil, err
	}

	if def.File == "" {
		// some cgo defs have empty File; omit them
		return nil, nil
	}

	return def, nil
}

func convertGoRef(gr *gog.Ref, repoURI string) (*graph.Ref, error) {
	resolvedTarget, err := ResolveDep(gr.Def.PackageImportPath, repoURI)
	if err != nil {
		return nil, err
	}
	if resolvedTarget == nil {
		return nil, nil
	}

	return &graph.Ref{
		DefRepo:     uriOrEmpty(resolvedTarget.ToRepoCloneURL),
		DefPath:     graph.DefPath(pathOrDot(strings.Join(gr.Def.Path, "/"))),
		DefUnit:     resolvedTarget.ToUnit,
		DefUnitType: resolvedTarget.ToUnitType,
		Def:         gr.IsDef,
		File:        gr.File,
		Start:       gr.Span[0],
		End:         gr.Span[1],
	}, nil
}

func convertGoDoc(gd *gog.Doc, repoURI string) (*graph.Doc, error) {
	resolvedTarget, err := ResolveDep(gd.PackageImportPath, repoURI)
	if err != nil {
		return nil, err
	}
	return &graph.Doc{
		DefKey: graph.DefKey{
			Path:     graph.DefPath(pathOrDot(strings.Join(gd.Path, "/"))),
			Unit:     resolvedTarget.ToUnit,
			UnitType: resolvedTarget.ToUnitType,
		},
		Format: gd.Format,
		Data:   gd.Data,
		File:   gd.File,
		Start:  gd.Span[0],
		End:    gd.Span[1],
	}, nil
}

func uriOrEmpty(cloneURL string) repo.URI {
	if cloneURL == "" {
		return ""
	}
	return repo.MakeURI(cloneURL)
}

func pathOrDot(path string) string {
	if path == "" {
		return "."
	}
	return path
}

func treePath(path string) graph.TreePath {
	if path == "" || path == "." {
		return graph.TreePath(".")
	}
	return graph.TreePath(fmt.Sprintf("./%s", path))
}

func doGraph(pkg *build.Package) (*gog.Output, error) {
	importPath := pkg.ImportPath

	// If we've overridden GOROOT and we're building a package not in
	// $GOROOT/src/pkg (such as "cmd/go"), then we need to virtualize GOROOT
	// because we can't set GOPATH=GOROOT (go/build ignores GOPATH in that
	// case).
	if config.GOROOT != "" && strings.HasPrefix(importPath, "cmd/") {
		// Unset our custom GOROOT (since we're routing FS ops to it using
		// vfs) and set it as our GOPATH.
		buildContext.GOROOT = build.Default.GOROOT
		buildContext.GOPATH = config.GOROOT

		virtualCWD = build.Default.GOROOT

		ns := vfs.NameSpace{}
		ns.Bind(filepath.Join(buildContext.GOROOT, "src/pkg"), vfs.OS(filepath.Join(config.GOROOT, "src/pkg")), "/", vfs.BindBefore)
		ns.Bind("/", vfs.OS("/"), "/", vfs.BindAfter)
		buildContext.IsDir = func(path string) bool {
			fi, err := ns.Stat(path)
			return err == nil && fi.Mode().IsDir()
		}
		buildContext.HasSubdir = func(root, dir string) (rel string, ok bool) { panic("unexpected") }
		buildContext.OpenFile = func(path string) (io.ReadCloser, error) {
			f, err := ns.Open(path)
			return f, err
		}
		buildContext.ReadDir = ns.ReadDir
	}

	if !loaderConfig.SourceImports {
		imports := map[string]struct{}{}
		for _, imp := range pkg.Imports {
			imports[imp] = struct{}{}
		}
		for _, imp := range pkg.TestImports {
			imports[imp] = struct{}{}
		}
		for _, imp := range pkg.XTestImports {
			imports[imp] = struct{}{}
		}

		for imp, _ := range imports {
			if imp == "C" {
				continue
			}
			cmd := exec.Command("go", "install", "-v", imp)
			cmd.Env = config.env()
			cmd.Stdout, cmd.Stderr = os.Stderr, os.Stderr
			log.Printf("Install %q: %v (env vars: %v)", importPath, cmd.Args, cmd.Env)
			if err := cmd.Run(); err != nil {
				return nil, err
			}
		}
	}

	importUnsafe := importPath == "unsafe"

	// Special-case: if this is a Cgo package, treat the CgoFiles as GoFiles or
	// else the character offsets will be junk.
	//
	// See https://codereview.appspot.com/86140043.
	loaderConfig.Build.CgoEnabled = false
	build.Default = *loaderConfig.Build
	if len(pkg.CgoFiles) > 0 {
		var allGoFiles []string
		allGoFiles = append(allGoFiles, pkg.GoFiles...)
		allGoFiles = append(allGoFiles, pkg.CgoFiles...)
		allGoFiles = append(allGoFiles, pkg.TestGoFiles...)
		for i, f := range allGoFiles {
			allGoFiles[i] = filepath.Join(cwd, pkg.Dir, f)
		}
		if err := loaderConfig.CreateFromFilenames(pkg.ImportPath, allGoFiles...); err != nil {
			return nil, err
		}
	} else {
		// Normal import
		if err := loaderConfig.ImportWithTests(importPath); err != nil {
			return nil, err
		}
	}

	if importUnsafe {
		// Special-case "unsafe" because go/loader does not let you load it
		// directly.
		if loaderConfig.ImportPkgs == nil {
			loaderConfig.ImportPkgs = make(map[string]bool)
		}
		loaderConfig.ImportPkgs["unsafe"] = true
	}

	prog, err := loaderConfig.Load()
	if err != nil {
		return nil, err
	}

	g := gog.New(prog)

	var pkgs []*loader.PackageInfo
	for _, pkg := range prog.Created {
		if strings.HasSuffix(pkg.Pkg.Name(), "_test") {
			// ignore xtest packages
			continue
		}
		pkgs = append(pkgs, pkg)
	}
	for _, pkg := range prog.Imported {
		pkgs = append(pkgs, pkg)
	}

	for _, pkg := range pkgs {
		if err := g.Graph(pkg); err != nil {
			return nil, err
		}
	}

	return &g.Output, nil
}
<|endoftext|>


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

// Package hash contains utility functions for hashing.
package hash

import (
	"crypto/rand"
	"encoding/binary"
	"fmt"

	"github.com/google/netstack/tcpip/header"
)

var hashIV = RandN32(1)[0]

// RandN32 generates a slice of n cryptographic random 32-bit numbers.
func RandN32(n int) []uint32 {
	b := make([]byte, 4*n)
	if _, err := rand.Read(b); err != nil {
		panic(fmt.Sprintf("unable to get random numbers: %v", err))
	}
	r := make([]uint32, n)
	for i := range r {
		r[i] = binary.LittleEndian.Uint32(b[4*i : (4*i + 4)])
	}
	return r
}

// Hash3Words calculates the Jenkins hash of 3 32-bit words. This is adapted
// from linux.
func Hash3Words(a, b, c, initval uint32) uint32 {
	const iv = 0xdeadbeef + (3 << 2)
	initval += iv

	a += initval
	b += initval
	c += initval

	c ^= b
	c -= rol32(b, 14)
	a ^= c
	a -= rol32(c, 11)
	b ^= a
	b -= rol32(a, 25)
	c ^= b
	c -= rol32(b, 16)
	a ^= c
	a -= rol32(c, 4)
	b ^= a
	b -= rol32(a, 14)
	c ^= b
	c -= rol32(b, 24)

	return c
}

// IPv4FragmentHash computes the hash of the IPv4 fragment as suggested in RFC 791.
func IPv4FragmentHash(h header.IPv4) uint32 {
	x := uint32(h.ID())<<16 | uint32(h.Protocol())
	t := h.SourceAddress()
	y := uint32(t[0]) | uint32(t[1])<<8 | uint32(t[2])<<16 | uint32(t[3])<<24
	t = h.DestinationAddress()
	z := uint32(t[0]) | uint32(t[1])<<8 | uint32(t[2])<<16 | uint32(t[3])<<24
	return Hash3Words(x, y, z, hashIV)
}

// IPv6FragmentHash computes the hash of the ipv6 fragment.
// Unlike IPv4, the protocol is not used to compute the hash.
// RFC 2640 (sec 4.5) is not very sharp on this aspect.
// As a reference, also Linux ignores the protocol to compute
// the hash (inet6_hash_frag).
func IPv6FragmentHash(h header.IPv6, f header.IPv6Fragment) uint32 {
	t := h.SourceAddress()
	y := uint32(t[0]) | uint32(t[1])<<8 | uint32(t[2])<<16 | uint32(t[3])<<24
	t = h.DestinationAddress()
	z := uint32(t[0]) | uint32(t[1])<<8 | uint32(t[2])<<16 | uint32(t[3])<<24
	return Hash3Words(f.ID(), y, z, hashIV)
}

func rol32(v, shift uint32) uint32 {
	return (v << shift) | (v >> ((-shift) & 31))
}
<commit_msg>Simplify simple panic string generation<commit_after>// Copyright 2017 The Netstack Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package hash contains utility functions for hashing.
package hash

import (
	"crypto/rand"
	"encoding/binary"

	"github.com/google/netstack/tcpip/header"
)

var hashIV = RandN32(1)[0]

// RandN32 generates a slice of n cryptographic random 32-bit numbers.
func RandN32(n int) []uint32 {
	b := make([]byte, 4*n)
	if _, err := rand.Read(b); err != nil {
		panic("unable to get random numbers: " + err.Error())
	}
	r := make([]uint32, n)
	for i := range r {
		r[i] = binary.LittleEndian.Uint32(b[4*i : (4*i + 4)])
	}
	return r
}

// Hash3Words calculates the Jenkins hash of 3 32-bit words. This is adapted
// from linux.
func Hash3Words(a, b, c, initval uint32) uint32 {
	const iv = 0xdeadbeef + (3 << 2)
	initval += iv

	a += initval
	b += initval
	c += initval

	c ^= b
	c -= rol32(b, 14)
	a ^= c
	a -= rol32(c, 11)
	b ^= a
	b -= rol32(a, 25)
	c ^= b
	c -= rol32(b, 16)
	a ^= c
	a -= rol32(c, 4)
	b ^= a
	b -= rol32(a, 14)
	c ^= b
	c -= rol32(b, 24)

	return c
}

// IPv4FragmentHash computes the hash of the IPv4 fragment as suggested in RFC 791.
func IPv4FragmentHash(h header.IPv4) uint32 {
	x := uint32(h.ID())<<16 | uint32(h.Protocol())
	t := h.SourceAddress()
	y := uint32(t[0]) | uint32(t[1])<<8 | uint32(t[2])<<16 | uint32(t[3])<<24
	t = h.DestinationAddress()
	z := uint32(t[0]) | uint32(t[1])<<8 | uint32(t[2])<<16 | uint32(t[3])<<24
	return Hash3Words(x, y, z, hashIV)
}

// IPv6FragmentHash computes the hash of the ipv6 fragment.
// Unlike IPv4, the protocol is not used to compute the hash.
// RFC 2640 (sec 4.5) is not very sharp on this aspect.
// As a reference, also Linux ignores the protocol to compute
// the hash (inet6_hash_frag).
func IPv6FragmentHash(h header.IPv6, f header.IPv6Fragment) uint32 {
	t := h.SourceAddress()
	y := uint32(t[0]) | uint32(t[1])<<8 | uint32(t[2])<<16 | uint32(t[3])<<24
	t = h.DestinationAddress()
	z := uint32(t[0]) | uint32(t[1])<<8 | uint32(t[2])<<16 | uint32(t[3])<<24
	return Hash3Words(f.ID(), y, z, hashIV)
}

func rol32(v, shift uint32) uint32 {
	return (v << shift) | (v >> ((-shift) & 31))
}
<|endoftext|>


<commit_before><commit_msg>Set language for JSON parser too.<commit_after><|endoftext|>


<commit_before>package video

import "io"
import "github.com/32bitkid/bitreader"
import "errors"
import "image"

var ErrUnsupportedVideoStream_ISO_IEC_11172_2 = errors.New("unsupported video stream ISO/IEC 11172-2")

type FrameProvider interface {
	Next() (image.Image, error)
}

func NewFrameProvider(source io.Reader) FrameProvider {
	return &frameProvider{
		NewVideoSequence(bitreader.NewBitReader(source)),
	}
}

type frameProvider struct {
	VideoSequence
}

func (self *frameProvider) Next() (image.Image, error) {

	// align to next start code
	if err := next_start_code(self); err != nil {
		panic(err)
	}

	// read sequence_header
	if err := self.sequence_header(); err != nil {
		panic(err)
	}

	// peek for sequence_extension
	if val, err := self.Peek32(32); err != nil {
		panic(err)
	} else if StartCode(val) == ExtensionStartCode {

		if err := self.sequence_extension(); err != nil {
			panic(err)
		}

		for {

			if err := extension_and_user_data(0, self); err != nil {
				panic("extension_and_user_data: " + err.Error())
			}

			for {
				if nextbits, err := self.Peek32(32); err != nil {
					panic("Peek32")
				} else if StartCode(nextbits) == GroupStartCode {
					if err := self.group_of_pictures_header(); err != nil {
						panic("group_of_pictures_header: " + err.Error())
					}
					if err := extension_and_user_data(1, self); err != nil {
						panic("extension_and_user_data:" + err.Error())
					}
				}

				if err := self.picture_header(); err != nil {
					panic("picture_header: " + err.Error())
				}

				if err := self.picture_coding_extension(); err != nil {
					panic("picture_coding_extension: " + err.Error())
				}

				if err := extension_and_user_data(2, self); err != nil {
					panic("extension_and_user_data: " + err.Error())
				}

				{
					frame, err := self.picture_data()
					if err != nil {
						panic(err)
					}
					if true {
						return frame, nil
					}
				}

				if nextbits, err := self.Peek32(32); err != nil {
					panic("peeking: " + err.Error())
				} else if StartCode(nextbits) == PictureStartCode {
					continue
				} else if StartCode(nextbits) == GroupStartCode {
					continue
				} else {
					break
				}
			}

			panic("not implemented: frame_provider")

			if nextbits, err := self.Peek32(32); err != nil {
				panic("Peek32")
			} else if StartCode(nextbits) == SequenceEndStartCode {
				break
			}

		}

		// SequenceEndStartCode
		return nil, self.Trash(32)
	} else {
		// Stream is MPEG-1 Video
		return nil, ErrUnsupportedVideoStream_ISO_IEC_11172_2
	}

}
<commit_msg>implementing video loop.<commit_after>package video

import "io"
import "github.com/32bitkid/bitreader"
import "errors"
import "image"

var ErrUnsupportedVideoStream_ISO_IEC_11172_2 = errors.New("unsupported video stream ISO/IEC 11172-2")

type FrameProvider interface {
	Next() (image.Image, error)
}

func NewFrameProvider(source io.Reader) FrameProvider {
	return &frameProvider{
		NewVideoSequence(bitreader.NewBitReader(source)),
	}
}

type frameProvider struct {
	VideoSequence
}

func (self *frameProvider) Next() (image.Image, error) {

	// align to next start code
	if err := next_start_code(self); err != nil {
		panic(err)
	}

	// read sequence_header
	if err := self.sequence_header(); err != nil {
		panic(err)
	}

	// peek for sequence_extension
	if val, err := self.Peek32(32); err != nil {
		panic(err)
	} else if StartCode(val) == ExtensionStartCode {

		if err := self.sequence_extension(); err != nil {
			panic(err)
		}

		for {

			if err := extension_and_user_data(0, self); err != nil {
				panic("extension_and_user_data: " + err.Error())
			}

			for {
				if nextbits, err := self.Peek32(32); err != nil {
					panic("Peek32")
				} else if StartCode(nextbits) == GroupStartCode {
					if err := self.group_of_pictures_header(); err != nil {
						panic("group_of_pictures_header: " + err.Error())
					}
					if err := extension_and_user_data(1, self); err != nil {
						panic("extension_and_user_data:" + err.Error())
					}
				}

				if err := self.picture_header(); err != nil {
					panic("picture_header: " + err.Error())
				}

				if err := self.picture_coding_extension(); err != nil {
					panic("picture_coding_extension: " + err.Error())
				}

				if err := extension_and_user_data(2, self); err != nil {
					panic("extension_and_user_data: " + err.Error())
				}

				{
					frame, err := self.picture_data()
					if err != nil {
						panic(err)
					}
					if true {
						return frame, nil
					}
				}

				if nextbits, err := self.Peek32(32); err != nil {
					panic("peeking: " + err.Error())
				} else if StartCode(nextbits) == PictureStartCode {
					continue
				} else if StartCode(nextbits) == GroupStartCode {
					continue
				} else {
					break
				}

			}

			if nextbits, err := self.Peek32(32); err != nil {
				panic("Peek32")
			} else if StartCode(nextbits) == SequenceEndStartCode {
				break
			}

			if err := self.sequence_header(); err != nil {
				panic(err)
			}

			if err := self.sequence_extension(); err != nil {
				panic(err)
			}

		}

		// SequenceEndStartCode
		return nil, self.Trash(32)
	} else {
		// Stream is MPEG-1 Video
		return nil, ErrUnsupportedVideoStream_ISO_IEC_11172_2
	}

}
<|endoftext|>


<commit_before>package vidlistener

import (
	"context"
	"os"
	"time"

	"github.com/golang/glog"
	"github.com/livepeer/lpms/segmenter"
	"github.com/livepeer/lpms/stream"
	joy4rtmp "github.com/nareix/joy4/format/rtmp"
)

var segOptions = segmenter.SegmenterOptions{SegLength: time.Second * 2}

type LocalStream struct {
	StreamID  string
	Timestamp int64
}

type VidListener struct {
	RtmpServer *joy4rtmp.Server
}

//HandleRTMPPublish immediately turns the RTMP stream into segmented HLS, and writes it into a stream.
//It exposes getStreamID so the user can name the stream, and getStream so the user can keep track of all the streams.
func (self *VidListener) HandleRTMPPublish(
	getStreamID func(reqPath string) (string, error),
	getStream func(reqPath string) (stream.Stream, stream.Stream, error),
	endStream func(reqPath string)) error {

	self.RtmpServer.HandlePublish = func(conn *joy4rtmp.Conn) {
		glog.Infof("RTMP server got upstream")

		_, err := getStreamID(conn.URL.Path)
		if err != nil {
			glog.Errorf("RTMP Stream Publish Error: %v", err)
			return
		}

		rs, hs, err := getStream(conn.URL.Path)
		if err != nil {
			glog.Errorf("RTMP Publish couldn't get a destination stream for %v", conn.URL.Path)
			return
		}
		// hlsS := stream.NewVideoStream(rs.GetStreamID() + ".m3u8")

		glog.Infof("Got RTMP Stream: %v", rs.GetStreamID())
		cew := make(chan error, 0)
		cs := make(chan error, 0)

		glog.Infof("Writing RTMP to stream")
		go func() { cew <- rs.WriteRTMPToStream(context.Background(), conn) }()
		go func() { cs <- self.segmentStream(rs, hs) }()

		select {
		case err := <-cew:
			endStream(conn.URL.Path)
			glog.Infof("Final stream length: %v", rs.Len())
			glog.Error("Got error writing RTMP: ", err)
		case err := <-cs:
			glog.Errorf("Error segmenting, %v", err)
		}

	}
	return nil
}

func (self *VidListener) segmentStream(rs stream.Stream, hs stream.Stream) error {
	// //Invoke Segmenter
	workDir, _ := os.Getwd()
	workDir = workDir + "/tmp"
	localRtmpUrl := "rtmp://localhost" + self.RtmpServer.Addr + "/stream/" + rs.GetStreamID()
	ctx := context.Background()
	s := segmenter.NewFFMpegVideoSegmenter(workDir, rs.GetStreamID(), localRtmpUrl, segOptions.SegLength)
	c := make(chan error, 1)
	go func() { c <- s.RTMPToHLS(ctx, segOptions) }()

	go func() {
		c <- func() error {
			for {
				pl, err := s.PollPlaylist(ctx)
				if err != nil {
					glog.Errorf("Got error polling playlist: %v", err)
					return err
				}
				// glog.Infof("Writing pl: %v", pl)
				hs.WriteHLSPlaylistToStream(*pl.Data)
			}
		}()
	}()

	go func() {
		c <- func() error {
			for {
				seg, err := s.PollSegment(ctx)
				if err != nil {
					return err
				}
				ss := stream.HLSSegment{Data: seg.Data, Name: seg.Name}
				glog.Infof("Writing stream: %v, len:%v", ss.Name, len(seg.Data))
				hs.WriteHLSSegmentToStream(ss)
			}
		}()
	}()
	select {
	case err := <-c:
		glog.Errorf("Error segmenting stream: %v", err)
		return err
	}
}
<commit_msg>cancel ffmpeg and segment subscription when stream is over<commit_after>package vidlistener

import (
	"context"
	"os"
	"time"

	"github.com/golang/glog"
	"github.com/livepeer/lpms/segmenter"
	"github.com/livepeer/lpms/stream"
	joy4rtmp "github.com/nareix/joy4/format/rtmp"
)

var segOptions = segmenter.SegmenterOptions{SegLength: time.Second * 2}

type LocalStream struct {
	StreamID  string
	Timestamp int64
}

type VidListener struct {
	RtmpServer *joy4rtmp.Server
}

//HandleRTMPPublish immediately turns the RTMP stream into segmented HLS, and writes it into a stream.
//It exposes getStreamID so the user can name the stream, and getStream so the user can keep track of all the streams.
func (self *VidListener) HandleRTMPPublish(
	getStreamID func(reqPath string) (string, error),
	getStream func(reqPath string) (stream.Stream, stream.Stream, error),
	endStream func(reqPath string)) error {

	self.RtmpServer.HandlePublish = func(conn *joy4rtmp.Conn) {
		glog.Infof("RTMP server got upstream")

		_, err := getStreamID(conn.URL.Path)
		if err != nil {
			glog.Errorf("RTMP Stream Publish Error: %v", err)
			return
		}

		rs, hs, err := getStream(conn.URL.Path)
		if err != nil {
			glog.Errorf("RTMP Publish couldn't get a destination stream for %v", conn.URL.Path)
			return
		}

		glog.Infof("Got RTMP Stream: %v", rs.GetStreamID())
		cew := make(chan error, 0)
		cs := make(chan error, 0)
		ctx, cancel := context.WithCancel(context.Background())
		glog.Infof("Writing RTMP to stream")
		go func() { cew <- rs.WriteRTMPToStream(ctx, conn) }()
		go func() { cs <- self.segmentStream(ctx, rs, hs) }()

		select {
		case err := <-cew:
			endStream(conn.URL.Path)
			glog.Infof("Final stream length: %v", rs.Len())
			glog.Error("Got error writing RTMP: ", err)
			cancel()
		case err := <-cs:
			glog.Errorf("Error segmenting, %v", err)
			cancel()
		}

	}
	return nil
}

func (self *VidListener) segmentStream(ctx context.Context, rs stream.Stream, hs stream.Stream) error {
	// //Invoke Segmenter
	workDir, _ := os.Getwd()
	workDir = workDir + "/tmp"
	localRtmpUrl := "rtmp://localhost" + self.RtmpServer.Addr + "/stream/" + rs.GetStreamID()
	s := segmenter.NewFFMpegVideoSegmenter(workDir, rs.GetStreamID(), localRtmpUrl, segOptions.SegLength)
	c := make(chan error, 1)
	go func() { c <- s.RTMPToHLS(ctx, segOptions) }()

	go func() {
		c <- func() error {
			for {
				pl, err := s.PollPlaylist(ctx)
				if err != nil {
					glog.Errorf("Got error polling playlist: %v", err)
					return err
				}
				// glog.Infof("Writing pl: %v", pl)
				hs.WriteHLSPlaylistToStream(*pl.Data)
			}
		}()
	}()

	go func() {
		c <- func() error {
			for {
				seg, err := s.PollSegment(ctx)
				if err != nil {
					return err
				}
				ss := stream.HLSSegment{Data: seg.Data, Name: seg.Name}
				glog.Infof("Writing stream: %v, len:%v", ss.Name, len(seg.Data))
				hs.WriteHLSSegmentToStream(ss)
			}
		}()
	}()

	select {
	case err := <-c:
		glog.Errorf("Error segmenting stream: %v", err)
		return err
	}
}
<|endoftext|>


<commit_before>package router

import (
	"bytes"
	"crypto/rand"
	"encoding/gob"
	"fmt"
	"net"

	"github.com/weaveworks/weave/common"
)

var log = common.Log

var void = struct{}{}

func checkFatal(e error) {
	if e != nil {
		log.Fatal(e)
	}
}

func checkWarn(e error) {
	if e != nil {
		log.Warnln(e)
	}
}

func PosixError(err error) error {
	if err == nil {
		return nil
	}
	operr, ok := err.(*net.OpError)
	if !ok {
		return nil
	}
	return operr.Err
}

func (mtbe MsgTooBigError) Error() string {
	return fmt.Sprint("Msg too big error. PMTU is ", mtbe.PMTU)
}

func (ftbe FrameTooBigError) Error() string {
	return fmt.Sprint("Frame too big error. Effective PMTU is ", ftbe.EPMTU)
}

func (upe UnknownPeerError) Error() string {
	return fmt.Sprint("Reference to unknown peer ", upe.Name)
}

func (nce NameCollisionError) Error() string {
	return fmt.Sprint("Multiple peers found with same name: ", nce.Name)
}

func (pde PacketDecodingError) Error() string {
	return fmt.Sprint("Failed to decode packet: ", pde.Desc)
}

func Concat(elems ...[]byte) []byte {
	res := []byte{}
	for _, e := range elems {
		res = append(res, e...)
	}
	return res
}

func randUint64() (r uint64) {
	buf := make([]byte, 8)
	_, err := rand.Read(buf)
	checkFatal(err)
	for _, v := range buf {
		r <<= 8
		r |= uint64(v)
	}
	return
}

func GobEncode(items ...interface{}) []byte {
	buf := new(bytes.Buffer)
	enc := gob.NewEncoder(buf)
	for _, i := range items {
		checkFatal(enc.Encode(i))
	}
	return buf.Bytes()
}

func macint(mac net.HardwareAddr) (r uint64) {
	for _, b := range mac {
		r <<= 8
		r |= uint64(b)
	}
	return
}

func intmac(key uint64) (r net.HardwareAddr) {
	r = make([]byte, 6)
	for i := 5; i >= 0; i-- {
		r[i] = byte(key)
		key >>= 8
	}
	return
}

type ListOfPeers []*Peer

func (lop ListOfPeers) Len() int {
	return len(lop)
}
func (lop ListOfPeers) Swap(i, j int) {
	lop[i], lop[j] = lop[j], lop[i]
}
func (lop ListOfPeers) Less(i, j int) bool {
	return lop[i].Name < lop[j].Name
}
<commit_msg>go 1.5 broke PMTU detection<commit_after>package router

import (
	"bytes"
	"crypto/rand"
	"encoding/gob"
	"fmt"
	"net"
	"os"

	"github.com/weaveworks/weave/common"
)

var log = common.Log

var void = struct{}{}

func checkFatal(e error) {
	if e != nil {
		log.Fatal(e)
	}
}

func checkWarn(e error) {
	if e != nil {
		log.Warnln(e)
	}
}

// Look inside an error produced by the net package to get to the
// syscall.Errno at the root of the problem.
func PosixError(err error) error {
	if operr, ok := err.(*net.OpError); ok {
		err = operr.Err
	}

	// go1.5 wraps an Errno inside a SyscallError inside an OpError
	if scerr, ok := err.(*os.SyscallError); ok {
		err = scerr.Err
	}

	return err
}

func (mtbe MsgTooBigError) Error() string {
	return fmt.Sprint("Msg too big error. PMTU is ", mtbe.PMTU)
}

func (ftbe FrameTooBigError) Error() string {
	return fmt.Sprint("Frame too big error. Effective PMTU is ", ftbe.EPMTU)
}

func (upe UnknownPeerError) Error() string {
	return fmt.Sprint("Reference to unknown peer ", upe.Name)
}

func (nce NameCollisionError) Error() string {
	return fmt.Sprint("Multiple peers found with same name: ", nce.Name)
}

func (pde PacketDecodingError) Error() string {
	return fmt.Sprint("Failed to decode packet: ", pde.Desc)
}

func Concat(elems ...[]byte) []byte {
	res := []byte{}
	for _, e := range elems {
		res = append(res, e...)
	}
	return res
}

func randUint64() (r uint64) {
	buf := make([]byte, 8)
	_, err := rand.Read(buf)
	checkFatal(err)
	for _, v := range buf {
		r <<= 8
		r |= uint64(v)
	}
	return
}

func GobEncode(items ...interface{}) []byte {
	buf := new(bytes.Buffer)
	enc := gob.NewEncoder(buf)
	for _, i := range items {
		checkFatal(enc.Encode(i))
	}
	return buf.Bytes()
}

func macint(mac net.HardwareAddr) (r uint64) {
	for _, b := range mac {
		r <<= 8
		r |= uint64(b)
	}
	return
}

func intmac(key uint64) (r net.HardwareAddr) {
	r = make([]byte, 6)
	for i := 5; i >= 0; i-- {
		r[i] = byte(key)
		key >>= 8
	}
	return
}

type ListOfPeers []*Peer

func (lop ListOfPeers) Len() int {
	return len(lop)
}
func (lop ListOfPeers) Swap(i, j int) {
	lop[i], lop[j] = lop[j], lop[i]
}
func (lop ListOfPeers) Less(i, j int) bool {
	return lop[i].Name < lop[j].Name
}
<|endoftext|>


<commit_before>/*
 Copyright 2021 The GoPlus Authors (goplus.org)
 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 builtin

import (
	"math/big"
)

type untyped_uint = uint

// -----------------------------------------------------------------------------
// type bigint

// A Bigint represents a signed multi-precision integer.
// The zero value for a Bigint represents the value 0.
type Bigint = *big.Int

func tmpint(a, b Bigint) Bigint {
	return new(big.Int)
}

func tmpint1(a Bigint) Bigint {
	return new(big.Int)
}

// Gopo_Bigint__Add: func (a bigint) + (b bigint) bigint
func Gopo_Bigint__Add(a, b Bigint) Bigint {
	return tmpint(a, b).Add(a, b)
}

// Gopo_Bigint__Sub: func (a bigint) - (b bigint) bigint
func Gopo_Bigint__Sub(a, b Bigint) Bigint {
	return tmpint(a, b).Sub(a, b)
}

// Gopo_Bigint__Mul: func (a bigint) * (b bigint) bigint
func Gopo_Bigint__Mul(a, b Bigint) Bigint {
	return tmpint(a, b).Mul(a, b)
}

// Gopo_Bigint__Quo: func (a bigint) / (b bigint) bigint {
func Gopo_Bigint__Quo(a, b Bigint) Bigint {
	return tmpint(a, b).Quo(a, b)
}

// Gopo_Bigint__Rem: func (a bigint) % (b bigint) bigint
func Gopo_Bigint__Rem(a, b Bigint) Bigint {
	return tmpint(a, b).Rem(a, b)
}

// Gopo_Bigint__Or: func (a bigint) | (b bigint) bigint
func Gopo_Bigint__Or(a, b Bigint) Bigint {
	return tmpint(a, b).Or(a, b)
}

// Gopo_Bigint__Xor: func (a bigint) ^ (b bigint) bigint
func Gopo_Bigint__Xor(a, b Bigint) Bigint {
	return tmpint(a, b).Xor(a, b)
}

// Gopo_Bigint__And: func (a bigint) & (b bigint) bigint
func Gopo_Bigint__And(a, b Bigint) Bigint {
	return tmpint(a, b).And(a, b)
}

// Gopo_Bigint__AndNot: func (a bigint) &^ (b bigint) bigint
func Gopo_Bigint__AndNot(a, b Bigint) Bigint {
	return tmpint(a, b).AndNot(a, b)
}

// Gopo_Bigint__Lsh: func (a bigint) << (n untyped_uint) bigint
func Gopo_Bigint__Lsh(a Bigint, n untyped_uint) Bigint {
	return tmpint1(a).Lsh(a, n)
}

// Gopo_Bigint__Rsh: func (a bigint) >> (n untyped_uint) bigint
func Gopo_Bigint__Rsh(a Bigint, n untyped_uint) Bigint {
	return tmpint1(a).Rsh(a, n)
}

// Gopo_Bigint__LT: func (a bigint) < (b bigint) bool
func Gopo_Bigint__LT(a, b Bigint) bool {
	return a.Cmp(b) < 0
}

// Gopo_Bigint__LE: func (a bigint) <= (b bigint) bool
func Gopo_Bigint__LE(a, b Bigint) bool {
	return a.Cmp(b) <= 0
}

// Gopo_Bigint__GT: func (a bigint) > (b bigint) bool
func Gopo_Bigint__GT(a, b Bigint) bool {
	return a.Cmp(b) > 0
}

// Gopo_Bigint__GE: func (a bigint) >= (b bigint) bool
func Gopo_Bigint__GE(a, b Bigint) bool {
	return a.Cmp(b) >= 0
}

// Gopo_Bigint__EQ: func (a bigint) == (b bigint) bool
func Gopo_Bigint__EQ(a, b Bigint) bool {
	return a.Cmp(b) == 0
}

// Gopo_Bigint__NE: func (a bigint) != (b bigint) bool
func Gopo_Bigint__NE(a, b Bigint) bool {
	return a.Cmp(b) != 0
}

// Gopo_Bigint__Neg: func -(a bigint) bigint
func Gopo_Bigint__Neg(a Bigint) Bigint {
	return tmpint1(a).Neg(a)
}

// Gopo_Bigint__Not: func ^(a bigint) bigint
func Gopo_Bigint__Not(a Bigint) Bigint {
	return tmpint1(a).Not(a)
}

// Gopc_Bigint__0: func bigint() bigint
func Gopc_Bigint__0() Bigint {
	return new(big.Int)
}

// Gopc_Bigint__1: func bigint(x int64) bigint
func Gopc_Bigint__1(x int64) Bigint {
	return big.NewInt(x)
}

// -----------------------------------------------------------------------------
// type bigrat

type Bigrat = *big.Rat

func tmprat(a, b Bigrat) Bigrat {
	return new(big.Rat)
}

func tmprat1(a Bigrat) Bigrat {
	return new(big.Rat)
}

// Gopo_Bigrat__Add: func (a bigrat) + (b bigrat) bigrat
func Gopo_Bigrat__Add(a, b Bigrat) Bigrat {
	return tmprat(a, b).Add(a, b)
}

// Gopo_Bigrat__Sub: func (a bigrat) - (b bigrat) bigrat
func Gopo_Bigrat__Sub(a, b Bigrat) Bigrat {
	return tmprat(a, b).Sub(a, b)
}

// Gopo_Bigrat__Mul: func (a bigrat) * (b bigrat) bigrat
func Gopo_Bigrat__Mul(a, b Bigrat) Bigrat {
	return tmprat(a, b).Mul(a, b)
}

// Gopo_Bigrat__Quo: func (a bigrat) / (b bigrat) bigrat
func Gopo_Bigrat__Quo(a, b Bigrat) Bigrat {
	return tmprat(a, b).Quo(a, b)
}

// Gopo_Bigrat__LT: func (a bigrat) < (b bigrat) bool
func Gopo_Bigrat__LT(a, b Bigrat) bool {
	return a.Cmp(b) < 0
}

// Gopo_Bigrat__LE: func (a bigrat) <= (b bigrat) bool
func Gopo_Bigrat__LE(a, b Bigrat) bool {
	return a.Cmp(b) <= 0
}

// Gopo_Bigrat__GT: func (a bigrat) > (b bigrat) bool
func Gopo_Bigrat__GT(a, b Bigrat) bool {
	return a.Cmp(b) > 0
}

// Gopo_Bigrat__GE: func (a bigrat) >= (b bigrat) bool
func Gopo_Bigrat__GE(a, b Bigrat) bool {
	return a.Cmp(b) >= 0
}

// Gopo_Bigrat__EQ: func (a bigrat) == (b bigrat) bool
func Gopo_Bigrat__EQ(a, b Bigrat) bool {
	return a.Cmp(b) == 0
}

// Gopo_Bigrat__NE: func (a bigrat) != (b bigrat) bool
func Gopo_Bigrat__NE(a, b Bigrat) bool {
	return a.Cmp(b) != 0
}

// Gopo_Bigrat__Neg: func -(a bigrat) bigrat
func Gopo_Bigrat__Neg(a Bigrat) Bigrat {
	return tmprat1(a).Neg(a)
}

// Gopo_Bigrat__Inv: func /(a bigrat) bigrat
func Gopo_Bigrat__Inv(a Bigrat) Bigrat {
	return tmprat1(a).Inv(a)
}

// Gopc_Bigrat__0: func bigrat() bigrat
func Gopc_Bigrat__0() Bigrat {
	return new(big.Rat)
}

// Gopc_Bigrat__1: func bigrat(a bigint) bigrat
func Gopc_Bigrat__1(a Bigint) Bigrat {
	return new(big.Rat).SetInt(a)
}

// Gopc_Bigrat__2: func bigrat(a, b int64) bigrat
func Gopc_Bigrat__2(a, b int64) Bigrat {
	return big.NewRat(a, b)
}

// -----------------------------------------------------------------------------
// type bigfloat

type Bigfloat = *big.Float

// -----------------------------------------------------------------------------
<commit_msg>zero value of bigint/bigrat is nil, not bigint(0), bigrat(0)<commit_after>/*
 Copyright 2021 The GoPlus Authors (goplus.org)
 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 builtin

import (
	"math/big"
)

type untyped_uint = uint

// -----------------------------------------------------------------------------
// type bigint

// A Bigint represents a signed multi-precision integer.
// The zero value for a Bigint represents nil.
type Bigint = *big.Int

func tmpint(a, b Bigint) Bigint {
	return new(big.Int)
}

func tmpint1(a Bigint) Bigint {
	return new(big.Int)
}

// Gopo_Bigint__Add: func (a bigint) + (b bigint) bigint
func Gopo_Bigint__Add(a, b Bigint) Bigint {
	return tmpint(a, b).Add(a, b)
}

// Gopo_Bigint__Sub: func (a bigint) - (b bigint) bigint
func Gopo_Bigint__Sub(a, b Bigint) Bigint {
	return tmpint(a, b).Sub(a, b)
}

// Gopo_Bigint__Mul: func (a bigint) * (b bigint) bigint
func Gopo_Bigint__Mul(a, b Bigint) Bigint {
	return tmpint(a, b).Mul(a, b)
}

// Gopo_Bigint__Quo: func (a bigint) / (b bigint) bigint {
func Gopo_Bigint__Quo(a, b Bigint) Bigint {
	return tmpint(a, b).Quo(a, b)
}

// Gopo_Bigint__Rem: func (a bigint) % (b bigint) bigint
func Gopo_Bigint__Rem(a, b Bigint) Bigint {
	return tmpint(a, b).Rem(a, b)
}

// Gopo_Bigint__Or: func (a bigint) | (b bigint) bigint
func Gopo_Bigint__Or(a, b Bigint) Bigint {
	return tmpint(a, b).Or(a, b)
}

// Gopo_Bigint__Xor: func (a bigint) ^ (b bigint) bigint
func Gopo_Bigint__Xor(a, b Bigint) Bigint {
	return tmpint(a, b).Xor(a, b)
}

// Gopo_Bigint__And: func (a bigint) & (b bigint) bigint
func Gopo_Bigint__And(a, b Bigint) Bigint {
	return tmpint(a, b).And(a, b)
}

// Gopo_Bigint__AndNot: func (a bigint) &^ (b bigint) bigint
func Gopo_Bigint__AndNot(a, b Bigint) Bigint {
	return tmpint(a, b).AndNot(a, b)
}

// Gopo_Bigint__Lsh: func (a bigint) << (n untyped_uint) bigint
func Gopo_Bigint__Lsh(a Bigint, n untyped_uint) Bigint {
	return tmpint1(a).Lsh(a, n)
}

// Gopo_Bigint__Rsh: func (a bigint) >> (n untyped_uint) bigint
func Gopo_Bigint__Rsh(a Bigint, n untyped_uint) Bigint {
	return tmpint1(a).Rsh(a, n)
}

// Gopo_Bigint__LT: func (a bigint) < (b bigint) bool
func Gopo_Bigint__LT(a, b Bigint) bool {
	return a.Cmp(b) < 0
}

// Gopo_Bigint__LE: func (a bigint) <= (b bigint) bool
func Gopo_Bigint__LE(a, b Bigint) bool {
	return a.Cmp(b) <= 0
}

// Gopo_Bigint__GT: func (a bigint) > (b bigint) bool
func Gopo_Bigint__GT(a, b Bigint) bool {
	return a.Cmp(b) > 0
}

// Gopo_Bigint__GE: func (a bigint) >= (b bigint) bool
func Gopo_Bigint__GE(a, b Bigint) bool {
	return a.Cmp(b) >= 0
}

// Gopo_Bigint__EQ: func (a bigint) == (b bigint) bool
func Gopo_Bigint__EQ(a, b Bigint) bool {
	return a.Cmp(b) == 0
}

// Gopo_Bigint__NE: func (a bigint) != (b bigint) bool
func Gopo_Bigint__NE(a, b Bigint) bool {
	return a.Cmp(b) != 0
}

// Gopo_Bigint__Neg: func -(a bigint) bigint
func Gopo_Bigint__Neg(a Bigint) Bigint {
	return tmpint1(a).Neg(a)
}

// Gopo_Bigint__Not: func ^(a bigint) bigint
func Gopo_Bigint__Not(a Bigint) Bigint {
	return tmpint1(a).Not(a)
}

// Gopc_Bigint__0: func bigint() bigint
func Gopc_Bigint__0() Bigint {
	return new(big.Int)
}

// Gopc_Bigint__1: func bigint(x int64) bigint
func Gopc_Bigint__1(x int64) Bigint {
	return big.NewInt(x)
}

// -----------------------------------------------------------------------------
// type bigrat

// A Bigrat represents a quotient a/b of arbitrary precision.
// The zero value for a Bigrat represents nil.
type Bigrat = *big.Rat

func tmprat(a, b Bigrat) Bigrat {
	return new(big.Rat)
}

func tmprat1(a Bigrat) Bigrat {
	return new(big.Rat)
}

// Gopo_Bigrat__Add: func (a bigrat) + (b bigrat) bigrat
func Gopo_Bigrat__Add(a, b Bigrat) Bigrat {
	return tmprat(a, b).Add(a, b)
}

// Gopo_Bigrat__Sub: func (a bigrat) - (b bigrat) bigrat
func Gopo_Bigrat__Sub(a, b Bigrat) Bigrat {
	return tmprat(a, b).Sub(a, b)
}

// Gopo_Bigrat__Mul: func (a bigrat) * (b bigrat) bigrat
func Gopo_Bigrat__Mul(a, b Bigrat) Bigrat {
	return tmprat(a, b).Mul(a, b)
}

// Gopo_Bigrat__Quo: func (a bigrat) / (b bigrat) bigrat
func Gopo_Bigrat__Quo(a, b Bigrat) Bigrat {
	return tmprat(a, b).Quo(a, b)
}

// Gopo_Bigrat__LT: func (a bigrat) < (b bigrat) bool
func Gopo_Bigrat__LT(a, b Bigrat) bool {
	return a.Cmp(b) < 0
}

// Gopo_Bigrat__LE: func (a bigrat) <= (b bigrat) bool
func Gopo_Bigrat__LE(a, b Bigrat) bool {
	return a.Cmp(b) <= 0
}

// Gopo_Bigrat__GT: func (a bigrat) > (b bigrat) bool
func Gopo_Bigrat__GT(a, b Bigrat) bool {
	return a.Cmp(b) > 0
}

// Gopo_Bigrat__GE: func (a bigrat) >= (b bigrat) bool
func Gopo_Bigrat__GE(a, b Bigrat) bool {
	return a.Cmp(b) >= 0
}

// Gopo_Bigrat__EQ: func (a bigrat) == (b bigrat) bool
func Gopo_Bigrat__EQ(a, b Bigrat) bool {
	return a.Cmp(b) == 0
}

// Gopo_Bigrat__NE: func (a bigrat) != (b bigrat) bool
func Gopo_Bigrat__NE(a, b Bigrat) bool {
	return a.Cmp(b) != 0
}

// Gopo_Bigrat__Neg: func -(a bigrat) bigrat
func Gopo_Bigrat__Neg(a Bigrat) Bigrat {
	return tmprat1(a).Neg(a)
}

// Gopo_Bigrat__Inv: func /(a bigrat) bigrat
func Gopo_Bigrat__Inv(a Bigrat) Bigrat {
	return tmprat1(a).Inv(a)
}

// Gopc_Bigrat__0: func bigrat() bigrat
func Gopc_Bigrat__0() Bigrat {
	return new(big.Rat)
}

// Gopc_Bigrat__1: func bigrat(a bigint) bigrat
func Gopc_Bigrat__1(a Bigint) Bigrat {
	return new(big.Rat).SetInt(a)
}

// Gopc_Bigrat__2: func bigrat(a, b int64) bigrat
func Gopc_Bigrat__2(a, b int64) Bigrat {
	return big.NewRat(a, b)
}

// -----------------------------------------------------------------------------
// type bigfloat

type Bigfloat = *big.Float

// -----------------------------------------------------------------------------
<|endoftext|>


<commit_before>/*
Copyright 2014 The Kubernetes Authors.

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

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

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

package runtime

import (
	"fmt"
	"runtime"
	"sync"
	"time"

	"github.com/golang/glog"
)

var (
	// ReallyCrash controls the behavior of HandleCrash and now defaults
	// true. It's still exposed so components can optionally set to false
	// to restore prior behavior.
	ReallyCrash = true
)

// PanicHandlers is a list of functions which will be invoked when a panic happens.
var PanicHandlers = []func(interface{}){logPanic}

// HandleCrash simply catches a crash and logs an error. Meant to be called via
// defer.  Additional context-specific handlers can be provided, and will be
// called in case of panic.  HandleCrash actually crashes, after calling the
// handlers and logging the panic message.
//
// TODO: remove this function. We are switching to a world where it's safe for
// apiserver to panic, since it will be restarted by kubelet. At the beginning
// of the Kubernetes project, nothing was going to restart apiserver and so
// catching panics was important. But it's actually much simpler for montoring
// software if we just exit when an unexpected panic happens.
func HandleCrash(additionalHandlers ...func(interface{})) {
	if r := recover(); r != nil {
		for _, fn := range PanicHandlers {
			fn(r)
		}
		for _, fn := range additionalHandlers {
			fn(r)
		}
		if ReallyCrash {
			// Actually proceed to panic.
			panic(r)
		}
	}
}

// logPanic logs the caller tree when a panic occurs.
func logPanic(r interface{}) {
	callers := getCallers(r)
	glog.Errorf("Observed a panic: %#v (%v)\n%v", r, r, callers)
}

func getCallers(r interface{}) string {
	callers := ""
	for i := 0; true; i++ {
		_, file, line, ok := runtime.Caller(i)
		if !ok {
			break
		}
		callers = callers + fmt.Sprintf("%v:%v\n", file, line)
	}

	return callers
}

// ErrorHandlers is a list of functions which will be invoked when an unreturnable
// error occurs.
// TODO(lavalamp): for testability, this and the below HandleError function
// should be packaged up into a testable and reusable object.
var ErrorHandlers = []func(error){
	logError,
	(&rudimentaryErrorBackoff{
		lastErrorTime: time.Now(),
		minPeriod:     500 * time.Millisecond,
	}).OnError,
}

// HandlerError is a method to invoke when a non-user facing piece of code cannot
// return an error and needs to indicate it has been ignored. Invoking this method
// is preferable to logging the error - the default behavior is to log but the
// errors may be sent to a remote server for analysis.
func HandleError(err error) {
	// this is sometimes called with a nil error.  We probably shouldn't fail and should do nothing instead
	if err == nil {
		return
	}

	for _, fn := range ErrorHandlers {
		fn(err)
	}
}

// logError prints an error with the call stack of the location it was reported
func logError(err error) {
	glog.ErrorDepth(2, err)
}

type rudimentaryErrorBackoff struct {
	minPeriod time.Duration // immutable
	// TODO(lavalamp): use the clock for testability. Need to move that
	// package for that to be accessible here.
	lastErrorTimeLock sync.Mutex
	lastErrorTime     time.Time
}

// OnError will block if it is called more often than the embedded period time.
// This will prevent overly tight hot error loops.
func (r *rudimentaryErrorBackoff) OnError(error) {
	r.lastErrorTimeLock.Lock()
	defer r.lastErrorTimeLock.Unlock()
	d := time.Since(r.lastErrorTime)
	if d < r.minPeriod {
		time.Sleep(r.minPeriod - d)
	}
	r.lastErrorTime = time.Now()
}

// GetCaller returns the caller of the function that calls it.
func GetCaller() string {
	var pc [1]uintptr
	runtime.Callers(3, pc[:])
	f := runtime.FuncForPC(pc[0])
	if f == nil {
		return fmt.Sprintf("Unable to find caller")
	}
	return f.Name()
}

// RecoverFromPanic replaces the specified error with an error containing the
// original error, and  the call tree when a panic occurs. This enables error
// handlers to handle errors and panics the same way.
func RecoverFromPanic(err *error) {
	if r := recover(); r != nil {
		callers := getCallers(r)

		*err = fmt.Errorf(
			"recovered from panic %q. (err=%v) Call stack:\n%v",
			r,
			*err,
			callers)
	}
}
<commit_msg>Adjust global log limit to 1ms<commit_after>/*
Copyright 2014 The Kubernetes Authors.

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

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

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

package runtime

import (
	"fmt"
	"runtime"
	"sync"
	"time"

	"github.com/golang/glog"
)

var (
	// ReallyCrash controls the behavior of HandleCrash and now defaults
	// true. It's still exposed so components can optionally set to false
	// to restore prior behavior.
	ReallyCrash = true
)

// PanicHandlers is a list of functions which will be invoked when a panic happens.
var PanicHandlers = []func(interface{}){logPanic}

// HandleCrash simply catches a crash and logs an error. Meant to be called via
// defer.  Additional context-specific handlers can be provided, and will be
// called in case of panic.  HandleCrash actually crashes, after calling the
// handlers and logging the panic message.
//
// TODO: remove this function. We are switching to a world where it's safe for
// apiserver to panic, since it will be restarted by kubelet. At the beginning
// of the Kubernetes project, nothing was going to restart apiserver and so
// catching panics was important. But it's actually much simpler for montoring
// software if we just exit when an unexpected panic happens.
func HandleCrash(additionalHandlers ...func(interface{})) {
	if r := recover(); r != nil {
		for _, fn := range PanicHandlers {
			fn(r)
		}
		for _, fn := range additionalHandlers {
			fn(r)
		}
		if ReallyCrash {
			// Actually proceed to panic.
			panic(r)
		}
	}
}

// logPanic logs the caller tree when a panic occurs.
func logPanic(r interface{}) {
	callers := getCallers(r)
	glog.Errorf("Observed a panic: %#v (%v)\n%v", r, r, callers)
}

func getCallers(r interface{}) string {
	callers := ""
	for i := 0; true; i++ {
		_, file, line, ok := runtime.Caller(i)
		if !ok {
			break
		}
		callers = callers + fmt.Sprintf("%v:%v\n", file, line)
	}

	return callers
}

// ErrorHandlers is a list of functions which will be invoked when an unreturnable
// error occurs.
// TODO(lavalamp): for testability, this and the below HandleError function
// should be packaged up into a testable and reusable object.
var ErrorHandlers = []func(error){
	logError,
	(&rudimentaryErrorBackoff{
		lastErrorTime: time.Now(),
		// 1ms was the number folks were able to stomach as a global rate limit.
		// If you need to log errors more than 1000 times a second you
		// should probably consider fixing your code instead. :)
		minPeriod: time.Millisecond,
	}).OnError,
}

// HandlerError is a method to invoke when a non-user facing piece of code cannot
// return an error and needs to indicate it has been ignored. Invoking this method
// is preferable to logging the error - the default behavior is to log but the
// errors may be sent to a remote server for analysis.
func HandleError(err error) {
	// this is sometimes called with a nil error.  We probably shouldn't fail and should do nothing instead
	if err == nil {
		return
	}

	for _, fn := range ErrorHandlers {
		fn(err)
	}
}

// logError prints an error with the call stack of the location it was reported
func logError(err error) {
	glog.ErrorDepth(2, err)
}

type rudimentaryErrorBackoff struct {
	minPeriod time.Duration // immutable
	// TODO(lavalamp): use the clock for testability. Need to move that
	// package for that to be accessible here.
	lastErrorTimeLock sync.Mutex
	lastErrorTime     time.Time
}

// OnError will block if it is called more often than the embedded period time.
// This will prevent overly tight hot error loops.
func (r *rudimentaryErrorBackoff) OnError(error) {
	r.lastErrorTimeLock.Lock()
	defer r.lastErrorTimeLock.Unlock()
	d := time.Since(r.lastErrorTime)
	if d < r.minPeriod {
		time.Sleep(r.minPeriod - d)
	}
	r.lastErrorTime = time.Now()
}

// GetCaller returns the caller of the function that calls it.
func GetCaller() string {
	var pc [1]uintptr
	runtime.Callers(3, pc[:])
	f := runtime.FuncForPC(pc[0])
	if f == nil {
		return fmt.Sprintf("Unable to find caller")
	}
	return f.Name()
}

// RecoverFromPanic replaces the specified error with an error containing the
// original error, and  the call tree when a panic occurs. This enables error
// handlers to handle errors and panics the same way.
func RecoverFromPanic(err *error) {
	if r := recover(); r != nil {
		callers := getCallers(r)

		*err = fmt.Errorf(
			"recovered from panic %q. (err=%v) Call stack:\n%v",
			r,
			*err,
			callers)
	}
}
<|endoftext|>


<commit_before>package QesyDb

func (m *Model)SetTable(Str string) *Model {
    m.Table = "str"
    return m
}

func (m *Model)SetWhere(Cond interface{}) *Model {
    m.Cond = Cond
    return m
}

func (m *Model)SetInsert(InsertMap map[string]string) *Model {
    m.Insert = InsertMap
    return m
}

func (m *Model)SetUpdate(UpdateMap map[string]string) *Model {
    m.Update = UpdateMap
    return m
}

func (m *Model)SetField(Field string) *Model {
    m.Field = Field
    return m
}

func (m *Model)SetIndex(Index string) *Model {
    m.Index = Index
    return m
}

func (m *Model)SetLimit(Limit interface{}) *Model {
    m.Limit = Limit
    return m
}

func (m *Model)SetSort(Sort string) *Model {
    m.Sort = Sort
    return m
}

func (m *Model)SetFetch(Fetch int) *Model {
    m.Fetch = Fetch
    return m
}<commit_msg>fix bugs<commit_after>package QesyDb

func (m *Model)SetTable(Str string) *Model {
    m.Table = Str
    return m
}

func (m *Model)SetWhere(Cond interface{}) *Model {
    m.Cond = Cond
    return m
}

func (m *Model)SetInsert(InsertMap map[string]string) *Model {
    m.Insert = InsertMap
    return m
}

func (m *Model)SetUpdate(UpdateMap map[string]string) *Model {
    m.Update = UpdateMap
    return m
}

func (m *Model)SetField(Field string) *Model {
    m.Field = Field
    return m
}

func (m *Model)SetIndex(Index string) *Model {
    m.Index = Index
    return m
}

func (m *Model)SetLimit(Limit interface{}) *Model {
    m.Limit = Limit
    return m
}

func (m *Model)SetSort(Sort string) *Model {
    m.Sort = Sort
    return m
}

func (m *Model)SetFetch(Fetch int) *Model {
    m.Fetch = Fetch
    return m
}<|endoftext|>