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

// Command webspin is an HTTP frontend that serves Upspin content
// accessible to the current user (as configured by upspin/rc).
package main

import (
	"fmt"
	"html/template"
	"net/http"
	"strings"

	"upspin.io/client"
	"upspin.io/context"
	"upspin.io/flags"
	"upspin.io/log"
	"upspin.io/path"
	"upspin.io/upspin"

	// Load required transports
	_ "upspin.io/dir/transports"
	_ "upspin.io/key/transports"
	_ "upspin.io/store/transports"
)

func main() {
	flags.Parse("https")
	http.Handle("/", newServer())
	log.Fatal(http.ListenAndServe(flags.HTTPSAddr, nil))
}

type server struct {
	cli upspin.Client
}

func newServer() *server {
	ctx, err := context.InitContext(nil)
	if err != nil {
		log.Fatal(err)
	}
	return &server{cli: client.New(ctx)}
}

func (s *server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if r.URL.Path == "/" {
		fmt.Fprintln(w, "Hello")
		return
	}

	urlName := upspin.PathName(strings.TrimPrefix(r.URL.Path, "/"))
	p, err := path.Parse(urlName)
	if err != nil {
		http.Error(w, "Parse: "+err.Error(), http.StatusBadRequest)
		return
	}

	// If the parsed path differs from the requested path, redirect.
	name := p.Path()
	if name != urlName {
		http.Redirect(w, r, "/"+string(name), http.StatusFound)
		return
	}

	des, err := s.cli.Glob(string(name))
	if err != nil {
		http.Error(w, "Glob: "+err.Error(), http.StatusInternalServerError)
		return
	}
	if len(des) == 0 {
		http.Error(w, "not found", http.StatusNotFound)
		return
	}

	if len(des) > 1 || des[0].IsDir() {
		// Display glob listing or directory contents.
		var d dirTemplateData
		if len(des) > 1 {
			d.Glob = name
			d.Content = des
		} else {
			d.Dir = des[0]
			d.Content, err = s.cli.Glob(string(name) + "/*")
			if err != nil {
				http.Error(w, "Glob: "+err.Error(), http.StatusInternalServerError)
				return
			}
			if p.NElem() > 0 {
				d.Parent = p.Drop(1).Path()
			}
		}
		if err := dirTemplate.Execute(w, d); err != nil {
			log.Error.Printf("rendering directory template: %v", err)
		}
		return
	}

	// Serve the file.
	data, err := s.cli.Get(name)
	if err != nil {
		http.Error(w, "Get: "+err.Error(), http.StatusInternalServerError)
		return
	}
	w.Write(data)
}

type dirTemplateData struct {
	// One and only one of these must be set.
	Dir  *upspin.DirEntry
	Glob upspin.PathName

	Parent  upspin.PathName
	Content []*upspin.DirEntry
}

var templateFuncs = template.FuncMap{
	"shortname": func(name upspin.PathName) upspin.PathName {
		parent := path.DropPath(name, 1)
		if name == parent {
			return name
		}
		if !strings.HasSuffix(string(parent), "/") {
			parent += "/"
		}
		return upspin.PathName(strings.TrimPrefix(string(name), string(parent)))
	},
}

var dirTemplate = template.Must(template.New("dir").Funcs(templateFuncs).Parse(`
{{with .Dir}}

Index of {{.Name}}

{{end}}
{{with .Glob}}

Matches for {{.}}

{{end}}

{{with .Parent}}

../

{{end}}
{{range .Content}}

{{shortname .Name}}{{if .IsDir}}/{{end}}

{{end}}

`))
<commit_msg>cmd/webspin: Add _ imports to webspin.go.<commit_after>// Copyright 2016 The Upspin Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Command webspin is an HTTP frontend that serves Upspin content
// accessible to the current user (as configured by upspin/rc).
package main

import (
	"fmt"
	"html/template"
	"net/http"
	"strings"

	"upspin.io/client"
	"upspin.io/context"
	"upspin.io/flags"
	"upspin.io/log"
	"upspin.io/path"
	"upspin.io/upspin"

	// Load useful packers
	_ "upspin.io/pack/ee"
	_ "upspin.io/pack/plain"

	// Load required transports
	_ "upspin.io/dir/transports"
	_ "upspin.io/key/transports"
	_ "upspin.io/store/transports"
)

func main() {
	flags.Parse("https")
	http.Handle("/", newServer())
	log.Fatal(http.ListenAndServe(flags.HTTPSAddr, nil))
}

type server struct {
	cli upspin.Client
}

func newServer() *server {
	ctx, err := context.InitContext(nil)
	if err != nil {
		log.Fatal(err)
	}
	return &server{cli: client.New(ctx)}
}

func (s *server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if r.URL.Path == "/" {
		fmt.Fprintln(w, "Hello")
		return
	}

	urlName := upspin.PathName(strings.TrimPrefix(r.URL.Path, "/"))
	p, err := path.Parse(urlName)
	if err != nil {
		http.Error(w, "Parse: "+err.Error(), http.StatusBadRequest)
		return
	}

	// If the parsed path differs from the requested path, redirect.
	name := p.Path()
	if name != urlName {
		http.Redirect(w, r, "/"+string(name), http.StatusFound)
		return
	}

	des, err := s.cli.Glob(string(name))
	if err != nil {
		http.Error(w, "Glob: "+err.Error(), http.StatusInternalServerError)
		return
	}
	if len(des) == 0 {
		http.Error(w, "not found", http.StatusNotFound)
		return
	}

	if len(des) > 1 || des[0].IsDir() {
		// Display glob listing or directory contents.
		var d dirTemplateData
		if len(des) > 1 {
			d.Glob = name
			d.Content = des
		} else {
			d.Dir = des[0]
			d.Content, err = s.cli.Glob(string(name) + "/*")
			if err != nil {
				http.Error(w, "Glob: "+err.Error(), http.StatusInternalServerError)
				return
			}
			if p.NElem() > 0 {
				d.Parent = p.Drop(1).Path()
			}
		}
		if err := dirTemplate.Execute(w, d); err != nil {
			log.Error.Printf("rendering directory template: %v", err)
		}
		return
	}

	// Serve the file.
	data, err := s.cli.Get(name)
	if err != nil {
		http.Error(w, "Get: "+err.Error(), http.StatusInternalServerError)
		return
	}
	w.Write(data)
}

type dirTemplateData struct {
	// One and only one of these must be set.
	Dir  *upspin.DirEntry
	Glob upspin.PathName

	Parent  upspin.PathName
	Content []*upspin.DirEntry
}

var templateFuncs = template.FuncMap{
	"shortname": func(name upspin.PathName) upspin.PathName {
		parent := path.DropPath(name, 1)
		if name == parent {
			return name
		}
		if !strings.HasSuffix(string(parent), "/") {
			parent += "/"
		}
		return upspin.PathName(strings.TrimPrefix(string(name), string(parent)))
	},
}

var dirTemplate = template.Must(template.New("dir").Funcs(templateFuncs).Parse(`
{{with .Dir}}

Index of {{.Name}}

{{end}}
{{with .Glob}}

Matches for {{.}}

{{end}}

{{with .Parent}}

../

{{end}}
{{range .Content}}

{{shortname .Name}}{{if .IsDir}}/{{end}}

{{end}}

`))
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"net/http"
	"sort"
	"strconv"
	"strings"
	"time"

	"github.com/PuerkitoBio/exp/juggler"
	"github.com/PuerkitoBio/exp/juggler/msg"
	"github.com/gorilla/websocket"
)

var (
	commands    map[string]*cmd
	connections []*juggler.Client
)

func init() {
	commands = map[string]*cmd{
		"?":          helpCmd,
		"help":       helpCmd,
		"connect":    connectCmd,
		"disconnect": disconnectCmd,
		"send":       sendCmd,
		"close":      closeCmd,
		"call":       callCmd,
		"pub":        pubCmd,
		"sub":        subCmd,
		"unsb":       unsbCmd,
	}
}

type cmd struct {
	Usage   string
	MinArgs int
	Help    string
	Run     func(*cmd, ...string)
}

var helpCmd = &cmd{
	Usage:   "usage: ? or help",
	MinArgs: 0,
	Help:    "print this message",

	Run: func(_ *cmd, _ ...string) {
		keys := make([]string, 0, len(commands))
		for k := range commands {
			keys = append(keys, k)
		}
		sort.Strings(keys)
		for _, k := range keys {
			printf("- %s :\n\t%s\n\t%s\n", k, commands[k].Usage, commands[k].Help)
		}
	},
}

var connectCmd = &cmd{
	Usage:   "usage: connect [URL [PROTO]]",
	MinArgs: 0,
	Help:    fmt.Sprintf("connect to URL using subprotocol PROTO (defaults to %s)", *defaultSubprotoFlag),

	Run: func(_ *cmd, args ...string) {
		var d websocket.Dialer

		addr := *defaultConnFlag
		if len(args) > 0 {
			addr = args[0]
		}

		head := http.Header{"Sec-WebSocket-Protocol": {*defaultSubprotoFlag}}
		if len(args) > 1 {
			head.Set("Sec-WebSocket-Protocol", args[1])
		}

		conn, err := juggler.Dial(&d, addr, head, connMsgLogger(len(connections)+1))
		if err != nil {
			printErr("error: %v", err)
			return
		}
		connections = append(connections, conn)
		printf("connected to %s [%d]", addr, len(connections))
	},
}

type connMsgLogger int

func (l connMsgLogger) Handle(m msg.Msg) {
	printf("[%d] %s %v", l, m.Type(), m.UUID())
}

var disconnectCmd = &cmd{
	Usage:   "usage: disconnect CONN_ID",
	MinArgs: 1,
	Help:    "disconnect the connection identified by CONN_ID",

	Run: func(cmd *cmd, args ...string) {
		if len(args) < cmd.MinArgs {
			printErr(cmd.Usage)
			return
		}
		if c, ix := getConn(args[0]); c != nil {
			c.Close()
			connections[ix] = nil
		} else {
			printErr("invalid connection ID")
		}
	},
}

var closeCmd = &cmd{
	Usage:   "usage: close CONN_ID [STATUS_TEXT]",
	MinArgs: 1,
	Help:    "cleanly close the connection identified by CONN_ID, sending a websocket Close message",

	Run: func(cmd *cmd, args ...string) {
		if len(args) < cmd.MinArgs {
			printErr(cmd.Usage)
			return
		}
		if c, ix := getConn(args[0]); c != nil {
			wsc := c.UnderlyingConn()
			st := "bye"
			if len(args) > 1 {
				st = args[1]
			}
			if err := wsc.WriteControl(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseGoingAway, st), time.Time{}); err != nil {
				printErr("failed to send close message: %v", err)
				return
			}
			c.Close()
			connections[ix] = nil
		} else {
			printErr("invalid connection ID")
		}
	},
}

var sendCmd = &cmd{
	Usage:   "usage: send CONN_ID MSG",
	MinArgs: 2,
	Help:    "send free-form MSG to the connection identified by CONN_ID",

	Run: func(cmd *cmd, args ...string) {
		if len(args) < cmd.MinArgs {
			printErr(cmd.Usage)
			return
		}
		if c, _ := getConn(args[0]); c != nil {
			wsc := c.UnderlyingConn()
			if err := wsc.WriteMessage(websocket.TextMessage, []byte(strings.Join(args[1:], " "))); err != nil {
				printErr("WriteMessage failed: %v", err)
				return
			}
		} else {
			printErr("invalid connection ID")
		}
	},
}

var callCmd = &cmd{
	Usage:   "usage: call CONN_ID URI [TIMEOUT_SEC [ARGS]]",
	MinArgs: 2,
	Help:    "send a CALL message to the connection identified by CONN_ID\n\tto URI with optional ARGS as JSON",

	Run: func(cmd *cmd, args ...string) {
		if len(args) < cmd.MinArgs {
			printErr(cmd.Usage)
			return
		}
		if c, ix := getConn(args[0]); c != nil {
			var to time.Duration
			if len(args) > 2 {
				d, err := time.ParseDuration(args[2])
				if err != nil {
					printErr("invalid timeout: %v", err)
					return
				}
				to = d
			}

			var v json.RawMessage
			if len(args) > 3 {
				v = json.RawMessage(strings.Join(args[3:], " "))
			}

			uuid, err := c.Call(args[1], v, to)
			if err != nil {
				printErr("failed to send CALL message: %v", err)
				return
			}
			printf("[%d] sent CALL message %v", ix, uuid)
		} else {
			printErr("invalid connection ID")
		}
	},
}

var pubCmd = &cmd{
	Usage:   "usage: pub CONN_ID CHANNEL [ARGS]",
	MinArgs: 2,
	Help:    "send a PUB message to the connection identified by CONN_ID\n\tto CHANNEL with optional ARGS as JSON",

	Run: func(cmd *cmd, args ...string) {
		if len(args) < cmd.MinArgs {
			printErr(cmd.Usage)
			return
		}
		if c, ix := getConn(args[0]); c != nil {
			var v json.RawMessage
			if len(args) > 2 {
				v = json.RawMessage(strings.Join(args[2:], " "))
			}

			uuid, err := c.Pub(args[1], v)
			if err != nil {
				printErr("failed to send PUB message: %v", err)
				return
			}
			printf("[%d] sent PUB message %v", ix, uuid)
		} else {
			printErr("invalid connection ID")
		}
	},
}

func getConn(arg string) (*juggler.Client, int) {
	ix, err := strconv.Atoi(arg)
	if err != nil {
		printErr("argument error: %v", err)
		return nil, 0
	}
	if ix > 0 && ix <= len(connections) {
		if c := connections[ix-1]; c != nil {
			return c, ix - 1
		}
	}
	return nil, 0
}
<commit_msg>juggler/cmd/wsclient: add sub/psub commands<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"net/http"
	"sort"
	"strconv"
	"strings"
	"time"

	"github.com/PuerkitoBio/exp/juggler"
	"github.com/PuerkitoBio/exp/juggler/msg"
	"github.com/gorilla/websocket"
)

var (
	commands    map[string]*cmd
	connections []*juggler.Client
)

func init() {
	commands = map[string]*cmd{
		"?":          helpCmd,
		"help":       helpCmd,
		"connect":    connectCmd,
		"disconnect": disconnectCmd,
		"send":       sendCmd,
		"close":      closeCmd,
		"call":       callCmd,
		"pub":        pubCmd,
		"sub":        subCmd,
		"psub":       psubCmd,
		"unsb":       unsbCmd,
		"punsb":      punsbCmd,
	}
}

type cmd struct {
	Usage   string
	MinArgs int
	Help    string
	Run     func(*cmd, ...string)
}

var helpCmd = &cmd{
	Usage:   "usage: ? or help",
	MinArgs: 0,
	Help:    "print this message",

	Run: func(_ *cmd, _ ...string) {
		keys := make([]string, 0, len(commands))
		for k := range commands {
			keys = append(keys, k)
		}
		sort.Strings(keys)
		for _, k := range keys {
			printf("- %s :\n\t%s\n\t%s\n", k, commands[k].Usage, commands[k].Help)
		}
	},
}

var connectCmd = &cmd{
	Usage:   "usage: connect [URL [PROTO]]",
	MinArgs: 0,
	Help:    fmt.Sprintf("connect to URL using subprotocol PROTO (defaults to %s)", *defaultSubprotoFlag),

	Run: func(_ *cmd, args ...string) {
		var d websocket.Dialer

		addr := *defaultConnFlag
		if len(args) > 0 {
			addr = args[0]
		}

		head := http.Header{"Sec-WebSocket-Protocol": {*defaultSubprotoFlag}}
		if len(args) > 1 {
			head.Set("Sec-WebSocket-Protocol", args[1])
		}

		conn, err := juggler.Dial(&d, addr, head, connMsgLogger(len(connections)+1))
		if err != nil {
			printErr("error: %v", err)
			return
		}
		connections = append(connections, conn)
		printf("connected to %s [%d]", addr, len(connections))
	},
}

type connMsgLogger int

func (l connMsgLogger) Handle(m msg.Msg) {
	printf("[%d] %s %v", l, m.Type(), m.UUID())
}

var disconnectCmd = &cmd{
	Usage:   "usage: disconnect CONN_ID",
	MinArgs: 1,
	Help:    "disconnect the connection identified by CONN_ID",

	Run: func(cmd *cmd, args ...string) {
		if len(args) < cmd.MinArgs {
			printErr(cmd.Usage)
			return
		}
		if c, ix := getConn(args[0]); c != nil {
			c.Close()
			connections[ix] = nil
		} else {
			printErr("invalid connection ID")
		}
	},
}

var closeCmd = &cmd{
	Usage:   "usage: close CONN_ID [STATUS_TEXT]",
	MinArgs: 1,
	Help:    "cleanly close the connection identified by CONN_ID, sending a websocket Close message",

	Run: func(cmd *cmd, args ...string) {
		if len(args) < cmd.MinArgs {
			printErr(cmd.Usage)
			return
		}
		if c, ix := getConn(args[0]); c != nil {
			wsc := c.UnderlyingConn()
			st := "bye"
			if len(args) > 1 {
				st = args[1]
			}
			if err := wsc.WriteControl(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseGoingAway, st), time.Time{}); err != nil {
				printErr("failed to send close message: %v", err)
				return
			}
			c.Close()
			connections[ix] = nil
		} else {
			printErr("invalid connection ID")
		}
	},
}

var sendCmd = &cmd{
	Usage:   "usage: send CONN_ID MSG",
	MinArgs: 2,
	Help:    "send raw MSG (sent as-is) to the connection identified by CONN_ID",

	Run: func(cmd *cmd, args ...string) {
		if len(args) < cmd.MinArgs {
			printErr(cmd.Usage)
			return
		}
		if c, _ := getConn(args[0]); c != nil {
			wsc := c.UnderlyingConn()
			if err := wsc.WriteMessage(websocket.TextMessage, []byte(strings.Join(args[1:], " "))); err != nil {
				printErr("WriteMessage failed: %v", err)
				return
			}
		} else {
			printErr("invalid connection ID")
		}
	},
}

var callCmd = &cmd{
	Usage:   "usage: call CONN_ID URI [TIMEOUT_SEC [ARGS]]",
	MinArgs: 2,
	Help:    "send a CALL message to the connection identified by CONN_ID\n\tto URI with optional ARGS as JSON",

	Run: func(cmd *cmd, args ...string) {
		if len(args) < cmd.MinArgs {
			printErr(cmd.Usage)
			return
		}
		if c, ix := getConn(args[0]); c != nil {
			var to time.Duration
			if len(args) > 2 {
				d, err := time.ParseDuration(args[2])
				if err != nil {
					printErr("invalid timeout: %v", err)
					return
				}
				to = d
			}

			var v json.RawMessage
			if len(args) > 3 {
				v = json.RawMessage(strings.Join(args[3:], " "))
			}

			uuid, err := c.Call(args[1], v, to)
			if err != nil {
				printErr("failed to send CALL message: %v", err)
				return
			}
			printf("[%d] sent CALL message %v", ix, uuid)
		} else {
			printErr("invalid connection ID")
		}
	},
}

var pubCmd = &cmd{
	Usage:   "usage: pub CONN_ID CHANNEL [ARGS]",
	MinArgs: 2,
	Help:    "send a PUB message to the connection identified by CONN_ID\n\tto CHANNEL with optional ARGS as JSON",

	Run: func(cmd *cmd, args ...string) {
		if len(args) < cmd.MinArgs {
			printErr(cmd.Usage)
			return
		}
		if c, ix := getConn(args[0]); c != nil {
			var v json.RawMessage
			if len(args) > 2 {
				v = json.RawMessage(strings.Join(args[2:], " "))
			}

			uuid, err := c.Pub(args[1], v)
			if err != nil {
				printErr("failed to send PUB message: %v", err)
				return
			}
			printf("[%d] sent PUB message %v", ix, uuid)
		} else {
			printErr("invalid connection ID")
		}
	},
}

var subCmd = &cmd{
	Usage:   "usage: sub CONN_ID CHANNEL",
	MinArgs: 2,
	Help:    "send a SUB message to the connection identified by CONN_ID\n\tto subscribe the connection to the CHANNEL",

	Run: getSubFunc(false),
}

var psubCmd = &cmd{
	Usage:   "usage: psub CONN_ID CHANNEL_PATTERN",
	MinArgs: 2,
	Help:    "send a SUB message to the connection identified by CONN_ID\n\tto subscribe the connection to the pattern CHANNEL_PATTERN",

	Run: getSubFunc(true),
}

func getSubFunc(pattern bool) func(*cmd, ...string) {
	return func(cmd *cmd, args ...string) {
		if len(args) < cmd.MinArgs {
			printErr(cmd.Usage)
			return
		}
		if c, ix := getConn(args[0]); c != nil {
			uuid, err := c.Sub(args[1], pattern)
			if err != nil {
				printErr("failed to send SUB message: %v", err)
				return
			}
			printf("[%d] sent SUB message %v", ix, uuid)
		} else {
			printErr("invalid connection ID")
		}
	}
}

func getConn(arg string) (*juggler.Client, int) {
	ix, err := strconv.Atoi(arg)
	if err != nil {
		printErr("argument error: %v", err)
		return nil, 0
	}
	if ix > 0 && ix <= len(connections) {
		if c := connections[ix-1]; c != nil {
			return c, ix - 1
		}
	}
	return nil, 0
}
<|endoftext|>


<commit_before>package container

import (
	"strings"

	"github.com/docker/engine-api/types/blkiodev"
	"github.com/docker/engine-api/types/strslice"
	"github.com/docker/go-connections/nat"
	"github.com/docker/go-units"
)

// NetworkMode represents the container network stack.
type NetworkMode string

// Isolation represents the isolation technology of a container. The supported
// values are platform specific
type Isolation string

// IsDefault indicates the default isolation technology of a container. On Linux this
// is the native driver. On Windows, this is a Windows Server Container.
func (i Isolation) IsDefault() bool {
	return strings.ToLower(string(i)) == "default" || string(i) == ""
}

// IpcMode represents the container ipc stack.
type IpcMode string

// IsPrivate indicates whether the container uses it's private ipc stack.
func (n IpcMode) IsPrivate() bool {
	return !(n.IsHost() || n.IsContainer())
}

// IsHost indicates whether the container uses the host's ipc stack.
func (n IpcMode) IsHost() bool {
	return n == "host"
}

// IsContainer indicates whether the container uses a container's ipc stack.
func (n IpcMode) IsContainer() bool {
	parts := strings.SplitN(string(n), ":", 2)
	return len(parts) > 1 && parts[0] == "container"
}

// Valid indicates whether the ipc stack is valid.
func (n IpcMode) Valid() bool {
	parts := strings.Split(string(n), ":")
	switch mode := parts[0]; mode {
	case "", "host":
	case "container":
		if len(parts) != 2 || parts[1] == "" {
			return false
		}
	default:
		return false
	}
	return true
}

// Container returns the name of the container ipc stack is going to be used.
func (n IpcMode) Container() string {
	parts := strings.SplitN(string(n), ":", 2)
	if len(parts) > 1 {
		return parts[1]
	}
	return ""
}

// UTSMode represents the UTS namespace of the container.
type UTSMode string

// IsPrivate indicates whether the container uses it's private UTS namespace.
func (n UTSMode) IsPrivate() bool {
	return !(n.IsHost())
}

// IsHost indicates whether the container uses the host's UTS namespace.
func (n UTSMode) IsHost() bool {
	return n == "host"
}

// Valid indicates whether the UTS namespace is valid.
func (n UTSMode) Valid() bool {
	parts := strings.Split(string(n), ":")
	switch mode := parts[0]; mode {
	case "", "host":
	default:
		return false
	}
	return true
}

// PidMode represents the pid stack of the container.
type PidMode string

// IsPrivate indicates whether the container uses it's private pid stack.
func (n PidMode) IsPrivate() bool {
	return !(n.IsHost())
}

// IsHost indicates whether the container uses the host's pid stack.
func (n PidMode) IsHost() bool {
	return n == "host"
}

// Valid indicates whether the pid stack is valid.
func (n PidMode) Valid() bool {
	parts := strings.Split(string(n), ":")
	switch mode := parts[0]; mode {
	case "", "host":
	default:
		return false
	}
	return true
}

// DeviceMapping represents the device mapping between the host and the container.
type DeviceMapping struct {
	PathOnHost        string
	PathInContainer   string
	CgroupPermissions string
}

// RestartPolicy represents the restart policies of the container.
type RestartPolicy struct {
	Name              string
	MaximumRetryCount int
}

// IsNone indicates whether the container has the "no" restart policy.
// This means the container will not automatically restart when exiting.
func (rp *RestartPolicy) IsNone() bool {
	return rp.Name == "no"
}

// IsAlways indicates whether the container has the "always" restart policy.
// This means the container will automatically restart regardless of the exit status.
func (rp *RestartPolicy) IsAlways() bool {
	return rp.Name == "always"
}

// IsOnFailure indicates whether the container has the "on-failure" restart policy.
// This means the contain will automatically restart of exiting with a non-zero exit status.
func (rp *RestartPolicy) IsOnFailure() bool {
	return rp.Name == "on-failure"
}

// IsUnlessStopped indicates whether the container has the
// "unless-stopped" restart policy. This means the container will
// automatically restart unless user has put it to stopped state.
func (rp *RestartPolicy) IsUnlessStopped() bool {
	return rp.Name == "unless-stopped"
}

// IsSame compares two RestartPolicy to see if they are the same
func (rp *RestartPolicy) IsSame(tp *RestartPolicy) bool {
	return rp.Name == tp.Name && rp.MaximumRetryCount == tp.MaximumRetryCount
}

// LogConfig represents the logging configuration of the container.
type LogConfig struct {
	Type   string
	Config map[string]string
}

// Resources contains container's resources (cgroups config, ulimits...)
type Resources struct {
	// Applicable to all platforms
	CPUShares int64 `json:"CpuShares"` // CPU shares (relative weight vs. other containers)

	// Applicable to UNIX platforms
	CgroupParent         string // Parent cgroup.
	BlkioWeight          uint16 // Block IO weight (relative weight vs. other containers)
	BlkioWeightDevice    []*blkiodev.WeightDevice
	BlkioDeviceReadBps   []*blkiodev.ThrottleDevice
	BlkioDeviceWriteBps  []*blkiodev.ThrottleDevice
	BlkioDeviceReadIOps  []*blkiodev.ThrottleDevice
	BlkioDeviceWriteIOps []*blkiodev.ThrottleDevice
	CPUPeriod            int64           `json:"CpuPeriod"` // CPU CFS (Completely Fair Scheduler) period
	CPUQuota             int64           `json:"CpuQuota"`  // CPU CFS (Completely Fair Scheduler) quota
	CpusetCpus           string          // CpusetCpus 0-2, 0,1
	CpusetMems           string          // CpusetMems 0-2, 0,1
	Devices              []DeviceMapping // List of devices to map inside the container
	KernelMemory         int64           // Kernel memory limit (in bytes)
	Memory               int64           // Memory limit (in bytes)
	MemoryReservation    int64           // Memory soft limit (in bytes)
	MemorySwap           int64           // Total memory usage (memory + swap); set `-1` to enable unlimited swap
	MemorySwappiness     *int64          // Tuning container memory swappiness behaviour
	OomKillDisable       *bool           // Whether to disable OOM Killer or not
	PidsLimit            int64           // Setting pids limit for a container
	Ulimits              []*units.Ulimit // List of ulimits to be set in the container
}

// UpdateConfig holds the mutable attributes of a Container.
// Those attributes can be updated at runtime.
type UpdateConfig struct {
	// Contains container's resources (cgroups, ulimits)
	Resources
	RestartPolicy RestartPolicy
}

// HostConfig the non-portable Config structure of a container.
// Here, "non-portable" means "dependent of the host we are running on".
// Portable information *should* appear in Config.
type HostConfig struct {
	// Applicable to all platforms
	Binds           []string      // List of volume bindings for this container
	ContainerIDFile string        // File (path) where the containerId is written
	LogConfig       LogConfig     // Configuration of the logs for this container
	NetworkMode     NetworkMode   // Network mode to use for the container
	PortBindings    nat.PortMap   // Port mapping between the exposed port (container) and the host
	RestartPolicy   RestartPolicy // Restart policy to be used for the container
	VolumeDriver    string        // Name of the volume driver used to mount volumes
	VolumesFrom     []string      // List of volumes to take from other container

	// Applicable to UNIX platforms
	CapAdd          strslice.StrSlice // List of kernel capabilities to add to the container
	CapDrop         strslice.StrSlice // List of kernel capabilities to remove from the container
	DNS             []string          `json:"Dns"`        // List of DNS server to lookup
	DNSOptions      []string          `json:"DnsOptions"` // List of DNSOption to look for
	DNSSearch       []string          `json:"DnsSearch"`  // List of DNSSearch to look for
	ExtraHosts      []string          // List of extra hosts
	GroupAdd        []string          // List of additional groups that the container process will run as
	IpcMode         IpcMode           // IPC namespace to use for the container
	Links           []string          // List of links (in the name:alias form)
	OomScoreAdj     int               // Container preference for OOM-killing
	PidMode         PidMode           // PID namespace to use for the container
	Privileged      bool              // Is the container in privileged mode
	PublishAllPorts bool              // Should docker publish all exposed port for the container
	ReadonlyRootfs  bool              // Is the container root filesystem in read-only
	SecurityOpt     []string          // List of string values to customize labels for MLS systems, such as SELinux.
	Tmpfs           map[string]string `json:",omitempty"` // List of tmpfs (mounts) used for the container
	UTSMode         UTSMode           // UTS namespace to use for the container
	ShmSize         int64             // Total shm memory usage

	// Applicable to Windows
	ConsoleSize [2]int    // Initial console size
	Isolation   Isolation // Isolation technology of the container (eg default, hyperv)

	// Contains container's resources (cgroups, ulimits)
	Resources
}
<commit_msg>Added Storage driver options for PR # 19367<commit_after>package container

import (
	"strings"

	"github.com/docker/engine-api/types/blkiodev"
	"github.com/docker/engine-api/types/strslice"
	"github.com/docker/go-connections/nat"
	"github.com/docker/go-units"
)

// NetworkMode represents the container network stack.
type NetworkMode string

// Isolation represents the isolation technology of a container. The supported
// values are platform specific
type Isolation string

// IsDefault indicates the default isolation technology of a container. On Linux this
// is the native driver. On Windows, this is a Windows Server Container.
func (i Isolation) IsDefault() bool {
	return strings.ToLower(string(i)) == "default" || string(i) == ""
}

// IpcMode represents the container ipc stack.
type IpcMode string

// IsPrivate indicates whether the container uses it's private ipc stack.
func (n IpcMode) IsPrivate() bool {
	return !(n.IsHost() || n.IsContainer())
}

// IsHost indicates whether the container uses the host's ipc stack.
func (n IpcMode) IsHost() bool {
	return n == "host"
}

// IsContainer indicates whether the container uses a container's ipc stack.
func (n IpcMode) IsContainer() bool {
	parts := strings.SplitN(string(n), ":", 2)
	return len(parts) > 1 && parts[0] == "container"
}

// Valid indicates whether the ipc stack is valid.
func (n IpcMode) Valid() bool {
	parts := strings.Split(string(n), ":")
	switch mode := parts[0]; mode {
	case "", "host":
	case "container":
		if len(parts) != 2 || parts[1] == "" {
			return false
		}
	default:
		return false
	}
	return true
}

// Container returns the name of the container ipc stack is going to be used.
func (n IpcMode) Container() string {
	parts := strings.SplitN(string(n), ":", 2)
	if len(parts) > 1 {
		return parts[1]
	}
	return ""
}

// UTSMode represents the UTS namespace of the container.
type UTSMode string

// IsPrivate indicates whether the container uses it's private UTS namespace.
func (n UTSMode) IsPrivate() bool {
	return !(n.IsHost())
}

// IsHost indicates whether the container uses the host's UTS namespace.
func (n UTSMode) IsHost() bool {
	return n == "host"
}

// Valid indicates whether the UTS namespace is valid.
func (n UTSMode) Valid() bool {
	parts := strings.Split(string(n), ":")
	switch mode := parts[0]; mode {
	case "", "host":
	default:
		return false
	}
	return true
}

// PidMode represents the pid stack of the container.
type PidMode string

// IsPrivate indicates whether the container uses it's private pid stack.
func (n PidMode) IsPrivate() bool {
	return !(n.IsHost())
}

// IsHost indicates whether the container uses the host's pid stack.
func (n PidMode) IsHost() bool {
	return n == "host"
}

// Valid indicates whether the pid stack is valid.
func (n PidMode) Valid() bool {
	parts := strings.Split(string(n), ":")
	switch mode := parts[0]; mode {
	case "", "host":
	default:
		return false
	}
	return true
}

// DeviceMapping represents the device mapping between the host and the container.
type DeviceMapping struct {
	PathOnHost        string
	PathInContainer   string
	CgroupPermissions string
}

// RestartPolicy represents the restart policies of the container.
type RestartPolicy struct {
	Name              string
	MaximumRetryCount int
}

// IsNone indicates whether the container has the "no" restart policy.
// This means the container will not automatically restart when exiting.
func (rp *RestartPolicy) IsNone() bool {
	return rp.Name == "no"
}

// IsAlways indicates whether the container has the "always" restart policy.
// This means the container will automatically restart regardless of the exit status.
func (rp *RestartPolicy) IsAlways() bool {
	return rp.Name == "always"
}

// IsOnFailure indicates whether the container has the "on-failure" restart policy.
// This means the contain will automatically restart of exiting with a non-zero exit status.
func (rp *RestartPolicy) IsOnFailure() bool {
	return rp.Name == "on-failure"
}

// IsUnlessStopped indicates whether the container has the
// "unless-stopped" restart policy. This means the container will
// automatically restart unless user has put it to stopped state.
func (rp *RestartPolicy) IsUnlessStopped() bool {
	return rp.Name == "unless-stopped"
}

// IsSame compares two RestartPolicy to see if they are the same
func (rp *RestartPolicy) IsSame(tp *RestartPolicy) bool {
	return rp.Name == tp.Name && rp.MaximumRetryCount == tp.MaximumRetryCount
}

// LogConfig represents the logging configuration of the container.
type LogConfig struct {
	Type   string
	Config map[string]string
}

// Resources contains container's resources (cgroups config, ulimits...)
type Resources struct {
	// Applicable to all platforms
	CPUShares int64 `json:"CpuShares"` // CPU shares (relative weight vs. other containers)

	// Applicable to UNIX platforms
	CgroupParent         string // Parent cgroup.
	BlkioWeight          uint16 // Block IO weight (relative weight vs. other containers)
	BlkioWeightDevice    []*blkiodev.WeightDevice
	BlkioDeviceReadBps   []*blkiodev.ThrottleDevice
	BlkioDeviceWriteBps  []*blkiodev.ThrottleDevice
	BlkioDeviceReadIOps  []*blkiodev.ThrottleDevice
	BlkioDeviceWriteIOps []*blkiodev.ThrottleDevice
	CPUPeriod            int64           `json:"CpuPeriod"` // CPU CFS (Completely Fair Scheduler) period
	CPUQuota             int64           `json:"CpuQuota"`  // CPU CFS (Completely Fair Scheduler) quota
	CpusetCpus           string          // CpusetCpus 0-2, 0,1
	CpusetMems           string          // CpusetMems 0-2, 0,1
	Devices              []DeviceMapping // List of devices to map inside the container
	KernelMemory         int64           // Kernel memory limit (in bytes)
	Memory               int64           // Memory limit (in bytes)
	MemoryReservation    int64           // Memory soft limit (in bytes)
	MemorySwap           int64           // Total memory usage (memory + swap); set `-1` to enable unlimited swap
	MemorySwappiness     *int64          // Tuning container memory swappiness behaviour
	OomKillDisable       *bool           // Whether to disable OOM Killer or not
	PidsLimit            int64           // Setting pids limit for a container
	Ulimits              []*units.Ulimit // List of ulimits to be set in the container
}

// UpdateConfig holds the mutable attributes of a Container.
// Those attributes can be updated at runtime.
type UpdateConfig struct {
	// Contains container's resources (cgroups, ulimits)
	Resources
	RestartPolicy RestartPolicy
}

// HostConfig the non-portable Config structure of a container.
// Here, "non-portable" means "dependent of the host we are running on".
// Portable information *should* appear in Config.
type HostConfig struct {
	// Applicable to all platforms
	Binds           []string      // List of volume bindings for this container
	ContainerIDFile string        // File (path) where the containerId is written
	LogConfig       LogConfig     // Configuration of the logs for this container
	NetworkMode     NetworkMode   // Network mode to use for the container
	PortBindings    nat.PortMap   // Port mapping between the exposed port (container) and the host
	RestartPolicy   RestartPolicy // Restart policy to be used for the container
	VolumeDriver    string        // Name of the volume driver used to mount volumes
	VolumesFrom     []string      // List of volumes to take from other container

	// Applicable to UNIX platforms
	CapAdd          strslice.StrSlice // List of kernel capabilities to add to the container
	CapDrop         strslice.StrSlice // List of kernel capabilities to remove from the container
	DNS             []string          `json:"Dns"`        // List of DNS server to lookup
	DNSOptions      []string          `json:"DnsOptions"` // List of DNSOption to look for
	DNSSearch       []string          `json:"DnsSearch"`  // List of DNSSearch to look for
	ExtraHosts      []string          // List of extra hosts
	GroupAdd        []string          // List of additional groups that the container process will run as
	IpcMode         IpcMode           // IPC namespace to use for the container
	Links           []string          // List of links (in the name:alias form)
	OomScoreAdj     int               // Container preference for OOM-killing
	PidMode         PidMode           // PID namespace to use for the container
	Privileged      bool              // Is the container in privileged mode
	PublishAllPorts bool              // Should docker publish all exposed port for the container
	ReadonlyRootfs  bool              // Is the container root filesystem in read-only
	SecurityOpt     []string          // List of string values to customize labels for MLS systems, such as SELinux.
	StorageOpt      []string          // Storage driver options per container.
	Tmpfs           map[string]string `json:",omitempty"` // List of tmpfs (mounts) used for the container
	UTSMode         UTSMode           // UTS namespace to use for the container
	ShmSize         int64             // Total shm memory usage

	// Applicable to Windows
	ConsoleSize [2]int    // Initial console size
	Isolation   Isolation // Isolation technology of the container (eg default, hyperv)

	// Contains container's resources (cgroups, ulimits)
	Resources
}
<|endoftext|>


<commit_before>package codegen

import (
	"fmt"
	"reflect"

	"github.com/bjwbell/gensimd/simd"

	"golang.org/x/tools/go/types"
)

type simdtype struct {
	name     string
	size     uint
	elemSize uint
	align    uint
}

func simdReflect(t reflect.Type) simdtype {
	elemSize := uint(0)
	if t.Kind() == reflect.Array {
		elemSize = uint(t.Elem().Size())
	}
	return simdtype{
		name:     t.Name(),
		size:     uint(t.Size()),
		elemSize: elemSize,
		align:    uint(t.Size()),
	}
}

func simdTypes() []simdtype {
	types := []simdtype{}
	types = append(types, simdReflect(reflect.TypeOf(simd.I8x16{})))
	types = append(types, simdReflect(reflect.TypeOf(simd.I16x8{})))
	types = append(types, simdReflect(reflect.TypeOf(simd.I32x4{})))
	types = append(types, simdReflect(reflect.TypeOf(simd.I64x2{})))

	types = append(types, simdReflect(reflect.TypeOf(simd.U8x16{})))
	types = append(types, simdReflect(reflect.TypeOf(simd.U16x8{})))
	types = append(types, simdReflect(reflect.TypeOf(simd.U32x4{})))
	types = append(types, simdReflect(reflect.TypeOf(simd.U64x2{})))

	types = append(types, simdReflect(reflect.TypeOf(simd.F32x4{})))
	types = append(types, simdReflect(reflect.TypeOf(simd.F64x2{})))
	return types
}

func isSimd(t types.Type) bool {
	if t, ok := t.(*types.Named); ok {
		tname := t.Obj()
		for _, simdType := range simdTypes() {
			if tname.Name() == simdType.name {
				return true
			}
		}
	}
	return false
}

func simdTypeInfo(t types.Type) (simdtype, error) {
	if !isSimd(t) {
		msg := fmt.Errorf("type (%v) is not simd type", t.String())
		return simdtype{}, msg
	}
	named := t.(*types.Named)
	tname := named.Obj()
	for _, simdType := range simdTypes() {
		if tname.Name() == simdType.name {
			return simdType, nil
		}
	}
	msg := fmt.Errorf("type (%v) couldn't find simd type info", t.String())
	return simdtype{}, msg
}

func simdHasElemSize(t types.Type) bool {
	if simdtype, err := simdTypeInfo(t); err == nil {
		return simdtype.elemSize > 0
	} else {
		panic(internal(fmt.Sprintf("type (%v) is not simd", t.String())))
	}
}

func simdElemSize(t types.Type) uint {
	if simdtype, err := simdTypeInfo(t); err == nil {
		return simdtype.elemSize
	} else {
		panic(internal(fmt.Sprintf("type (%v) is not simd", t.String())))

	}
}

func sizeofElem(t types.Type) uint {
	var e types.Type
	switch t := t.(type) {
	default:
		panic(internal(fmt.Sprintf("type (%v) not an array or slice\n", t.String())))
	case *types.Slice:
		e = t.Elem()
	case *types.Array:
		e = t.Elem()
	case *types.Named:
		if isSimd(t) && simdHasElemSize(t) {
			return simdElemSize(t)
		}
		panic(internal(
			fmt.Sprintf("t (%v), isSimd (%v)\n", t.String(), isSimd(t))))

	}
	return sizeof(e)
}

func sizeof(t types.Type) uint {

	switch t := t.(type) {
	case *types.Tuple:
		// TODO: usage of reflect most likely wrong!
		// uint(reflect.TypeOf(t).Elem().Size())
		panic("Tuples are unsupported")
	case *types.Basic:
		return sizeBasic(t.Kind())
	case *types.Pointer:
		return sizePtr()
	case *types.Slice:
		return sizeSlice(t)
	case *types.Array:
		return sizeArray(t)
	case *types.Named:
		if !isSimd(t) {
			panic("Named type is unsupported")
		}
		if info, err := simdTypeInfo(t); err != nil {
			panic(internal(fmt.Sprintf("Error unknown type in sizeof err:\"%v\"", err)))
		} else {
			return info.size
		}
	}
	panic(internal(fmt.Sprintf("unknown type: %v", t)))
}

func sizeArray(t *types.Array) uint {
	return uint(reflectType(t).Size())
}

func sizeSlice(t *types.Slice) uint {
	return uint(reflectType(t).Size())
}

func sizeInt() uint {
	return sizeBasic(types.Int)
}

func sizePtr() uint {
	typ := reflect.TypeOf(true)
	ptrType := reflect.PtrTo(typ)
	size := ptrType.Size()
	return uint(size)
}

// sizeBasic return the size in bytes of a basic type
func sizeBasic(b types.BasicKind) uint {
	return uint(reflectBasic(b).Size())
}

func align(t types.Type) uint {

	switch t := t.(type) {
	case *types.Tuple:
		return alignTuple(t)
	case *types.Basic:
		return alignBasic(t.Kind())
	case *types.Pointer:
		return alignPtr(t)
	case *types.Slice:
		return alignSlice(t)
	case *types.Array:
		return alignArray(t)
	case *types.Named:
		internal(fmt.Sprintf("Error unknown named type in align:\"%v\"", t))
	}
	panic(internal(fmt.Sprintf("Error unknown type (%v)", t)))
}

const tupleAlignment = 8

func alignTuple(tup *types.Tuple) uint {
	return tupleAlignment
}

func alignPtr(ptr *types.Pointer) uint {
	return uint(reflectType(ptr).Align())
}

func alignSlice(slice *types.Slice) uint {
	return uint(reflectType(slice).Align())
}

func alignArray(arr *types.Array) uint {
	return uint(reflectType(arr).Align())
}

func alignBasic(b types.BasicKind) uint {
	return uint(reflectBasic(b).Align())
}

func signed(t types.Type) bool {

	switch t := t.(type) {
	case *types.Basic:
		return signedBasic(t.Kind())
	}
	panic(internal(fmt.Sprintf("unknown type: %v", t)))
}

func signedBasic(b types.BasicKind) bool {
	switch b {
	case types.Bool:
		return false
	case types.Int, types.Int8, types.Int16, types.Int32, types.Int64:
		return true
	case types.Uint, types.Uint8, types.Uint16, types.Uint32, types.Uint64:
		return false
	case types.Float32, types.Float64:
		return true
	}
	panic(internal(fmt.Sprintf("unknown basic type (%v)", b)))
}

func isUint(t types.Type) bool {
	if t, ok := t.(*types.Basic); ok {
		switch t.Kind() {
		case types.Uint, types.Uint8, types.Uint16, types.Uint32, types.Uint64:
			return true
		}
	}
	return false
}
func isInt(t types.Type) bool {
	if t, ok := t.(*types.Basic); ok {
		switch t.Kind() {
		case types.Int, types.Int8, types.Int16, types.Int32, types.Int64:
			return true
		}
	}
	return false
}
func isInteger(t types.Type) bool {
	return isUint(t) || isInt(t)
}
func isBool(t types.Type) bool {
	return isBasicKind(t, types.Bool)
}

func isFloat(t types.Type) bool {
	return isFloat32(t) || isFloat64(t)
}

func isFloat32(t types.Type) bool {
	return isBasicKind(t, types.Float32)
}

func isFloat64(t types.Type) bool {
	return isBasicKind(t, types.Float64)
}

func isComplex(t types.Type) bool {
	return isBasicKind(t, types.Complex64) || isBasicKind(t, types.Complex128)
}

func isBasicKind(t types.Type, basickind types.BasicKind) bool {
	if t, ok := t.(*types.Basic); ok {
		return t.Kind() == basickind
	}
	return false
}

func isBasic(t types.Type) bool {
	_, ok := t.(*types.Basic)
	return ok
}

func reflectType(t types.Type) reflect.Type {
	switch t := t.(type) {
	case *types.Tuple:
		// TODO
	case *types.Basic:
		return reflectBasic(t.Kind())
	case *types.Pointer:
		return reflect.PtrTo(reflectType(t.Elem()))
	case *types.Slice:
		return reflect.SliceOf(reflectType(t.Elem()))
	case *types.Array:
		return reflect.ArrayOf(int(t.Len()), reflectType(t.Elem()))
	case *types.Named:
		// TODO
	}
	internal(fmt.Sprintf("error unknown type:\"%v\"", t))
	panic("")
}

func reflectBasic(b types.BasicKind) reflect.Type {
	switch b {
	default:
		panic(internal("unknown basic type"))
	case types.Bool:
		return reflect.TypeOf(true)
	case types.Int:
		return reflect.TypeOf(int(1))
	case types.Int8:
		return reflect.TypeOf(int8(1))
	case types.Int16:
		return reflect.TypeOf(int16(1))
	case types.Int32:
		return reflect.TypeOf(int32(1))
	case types.Int64:
		return reflect.TypeOf(int64(1))
	case types.Uint:
		return reflect.TypeOf(uint(1))
	case types.Uint8:
		return reflect.TypeOf(uint8(1))
	case types.Uint16:
		return reflect.TypeOf(uint16(1))
	case types.Uint32:
		return reflect.TypeOf(uint32(1))
	case types.Uint64:
		return reflect.TypeOf(uint64(1))
	case types.Float32:
		return reflect.TypeOf(float32(1))
	case types.Float64:
		return reflect.TypeOf(float64(1))
	}
}

var bInstrData = OpDataType{INTEGER_OP, InstrData{signed: false, size: 1}, XMM_INVALID}
var f32InstrData = OpDataType{XMM_OP, InstrData{}, XMM_F32}
var f64InstrData = OpDataType{XMM_OP, InstrData{}, XMM_F64}

func GetIntegerOpDataType(signed bool, size uint) OpDataType {
	instrdata := OpDataType{
		INTEGER_OP,
		InstrData{signed: signed, size: size},
		XMM_INVALID}
	return instrdata

}

func GetOpDataType(t types.Type) OpDataType {
	if isBool(t) {
		return bInstrData
	}
	if isFloat32(t) {
		return f32InstrData
	} else if isFloat64(t) {
		return f64InstrData
	}
	if isComplex(t) {
		panic("complex32/64 unsupported")
	}

	if isBasic(t) {
		return GetIntegerOpDataType(signed(t), sizeof(t))
	} else {
		panic(internal(fmt.Sprintf("non basic type \"%v\"", t)))
	}

}

func regType(t types.Type) RegType {
	if isFloat(t) {
		return XMM_REG
	}
	return DATA_REG
}
<commit_msg>Remove unneeded alignPtr, alignSlice, alignArray, alignBasic<commit_after>package codegen

import (
	"fmt"
	"reflect"

	"github.com/bjwbell/gensimd/simd"

	"golang.org/x/tools/go/types"
)

type simdtype struct {
	name     string
	size     uint
	elemSize uint
	align    uint
}

func simdReflect(t reflect.Type) simdtype {
	elemSize := uint(0)
	if t.Kind() == reflect.Array {
		elemSize = uint(t.Elem().Size())
	}
	return simdtype{
		name:     t.Name(),
		size:     uint(t.Size()),
		elemSize: elemSize,
		align:    uint(t.Size()),
	}
}

func simdTypes() []simdtype {
	types := []simdtype{}
	types = append(types, simdReflect(reflect.TypeOf(simd.I8x16{})))
	types = append(types, simdReflect(reflect.TypeOf(simd.I16x8{})))
	types = append(types, simdReflect(reflect.TypeOf(simd.I32x4{})))
	types = append(types, simdReflect(reflect.TypeOf(simd.I64x2{})))

	types = append(types, simdReflect(reflect.TypeOf(simd.U8x16{})))
	types = append(types, simdReflect(reflect.TypeOf(simd.U16x8{})))
	types = append(types, simdReflect(reflect.TypeOf(simd.U32x4{})))
	types = append(types, simdReflect(reflect.TypeOf(simd.U64x2{})))

	types = append(types, simdReflect(reflect.TypeOf(simd.F32x4{})))
	types = append(types, simdReflect(reflect.TypeOf(simd.F64x2{})))
	return types
}

func isSimd(t types.Type) bool {
	if t, ok := t.(*types.Named); ok {
		tname := t.Obj()
		for _, simdType := range simdTypes() {
			if tname.Name() == simdType.name {
				return true
			}
		}
	}
	return false
}

func simdTypeInfo(t types.Type) (simdtype, error) {
	if !isSimd(t) {
		msg := fmt.Errorf("type (%v) is not simd type", t.String())
		return simdtype{}, msg
	}
	named := t.(*types.Named)
	tname := named.Obj()
	for _, simdType := range simdTypes() {
		if tname.Name() == simdType.name {
			return simdType, nil
		}
	}
	msg := fmt.Errorf("type (%v) couldn't find simd type info", t.String())
	return simdtype{}, msg
}

func simdHasElemSize(t types.Type) bool {
	if simdtype, err := simdTypeInfo(t); err == nil {
		return simdtype.elemSize > 0
	} else {
		panic(internal(fmt.Sprintf("type (%v) is not simd", t.String())))
	}
}

func simdElemSize(t types.Type) uint {
	if simdtype, err := simdTypeInfo(t); err == nil {
		return simdtype.elemSize
	} else {
		panic(internal(fmt.Sprintf("type (%v) is not simd", t.String())))

	}
}

func sizeofElem(t types.Type) uint {
	var e types.Type
	switch t := t.(type) {
	default:
		panic(internal(fmt.Sprintf("type (%v) not an array or slice\n", t.String())))
	case *types.Slice:
		e = t.Elem()
	case *types.Array:
		e = t.Elem()
	case *types.Named:
		if isSimd(t) && simdHasElemSize(t) {
			return simdElemSize(t)
		}
		panic(internal(
			fmt.Sprintf("t (%v), isSimd (%v)\n", t.String(), isSimd(t))))

	}
	return sizeof(e)
}

func sizeof(t types.Type) uint {

	switch t := t.(type) {
	case *types.Tuple:
		// TODO: usage of reflect most likely wrong!
		// uint(reflect.TypeOf(t).Elem().Size())
		panic("Tuples are unsupported")
	case *types.Basic:
		return sizeBasic(t.Kind())
	case *types.Pointer:
		return sizePtr()
	case *types.Slice:
		return sizeSlice(t)
	case *types.Array:
		return sizeArray(t)
	case *types.Named:
		if !isSimd(t) {
			panic("Named type is unsupported")
		}
		if info, err := simdTypeInfo(t); err != nil {
			panic(internal(fmt.Sprintf("Error unknown type in sizeof err:\"%v\"", err)))
		} else {
			return info.size
		}
	}
	panic(internal(fmt.Sprintf("unknown type: %v", t)))
}

func sizeArray(t *types.Array) uint {
	return uint(reflectType(t).Size())
}

func sizeSlice(t *types.Slice) uint {
	return uint(reflectType(t).Size())
}

func sizeInt() uint {
	return sizeBasic(types.Int)
}

func sizePtr() uint {
	typ := reflect.TypeOf(true)
	ptrType := reflect.PtrTo(typ)
	size := ptrType.Size()
	return uint(size)
}

// sizeBasic return the size in bytes of a basic type
func sizeBasic(b types.BasicKind) uint {
	return uint(reflectBasic(b).Size())
}

func align(t types.Type) uint {

	switch t := t.(type) {
	case *types.Tuple:
		return alignTuple(t)
	case *types.Array, *types.Basic, *types.Pointer, *types.Slice:
		return uint(reflectType(t).Align())
	case *types.Named:
		if !isSimd(t) {
			panic("Named type is unsupported")
		}
		if info, err := simdTypeInfo(t); err != nil {
			panic(internal(fmt.Sprintf("unknown named type, err:\"%v\"", err)))
		} else {
			return info.align
		}
	}
	panic(internal(fmt.Sprintf("unknown type (%v)", t)))
}

const tupleAlignment = 8

func alignTuple(tup *types.Tuple) uint {
	return tupleAlignment
}

func signed(t types.Type) bool {

	switch t := t.(type) {
	case *types.Basic:
		return signedBasic(t.Kind())
	}
	panic(internal(fmt.Sprintf("unknown type: %v", t)))
}

func signedBasic(b types.BasicKind) bool {
	switch b {
	case types.Bool:
		return false
	case types.Int, types.Int8, types.Int16, types.Int32, types.Int64:
		return true
	case types.Uint, types.Uint8, types.Uint16, types.Uint32, types.Uint64:
		return false
	case types.Float32, types.Float64:
		return true
	}
	panic(internal(fmt.Sprintf("unknown basic type (%v)", b)))
}

func isUint(t types.Type) bool {
	if t, ok := t.(*types.Basic); ok {
		switch t.Kind() {
		case types.Uint, types.Uint8, types.Uint16, types.Uint32, types.Uint64:
			return true
		}
	}
	return false
}
func isInt(t types.Type) bool {
	if t, ok := t.(*types.Basic); ok {
		switch t.Kind() {
		case types.Int, types.Int8, types.Int16, types.Int32, types.Int64:
			return true
		}
	}
	return false
}
func isInteger(t types.Type) bool {
	return isUint(t) || isInt(t)
}
func isBool(t types.Type) bool {
	return isBasicKind(t, types.Bool)
}

func isFloat(t types.Type) bool {
	return isFloat32(t) || isFloat64(t)
}

func isFloat32(t types.Type) bool {
	return isBasicKind(t, types.Float32)
}

func isFloat64(t types.Type) bool {
	return isBasicKind(t, types.Float64)
}

func isComplex(t types.Type) bool {
	return isBasicKind(t, types.Complex64) || isBasicKind(t, types.Complex128)
}

func isBasicKind(t types.Type, basickind types.BasicKind) bool {
	if t, ok := t.(*types.Basic); ok {
		return t.Kind() == basickind
	}
	return false
}

func isBasic(t types.Type) bool {
	_, ok := t.(*types.Basic)
	return ok
}

func reflectType(t types.Type) reflect.Type {
	switch t := t.(type) {
	case *types.Tuple:
		// TODO
	case *types.Basic:
		return reflectBasic(t.Kind())
	case *types.Pointer:
		return reflect.PtrTo(reflectType(t.Elem()))
	case *types.Slice:
		return reflect.SliceOf(reflectType(t.Elem()))
	case *types.Array:
		return reflect.ArrayOf(int(t.Len()), reflectType(t.Elem()))
	case *types.Named:
		// TODO
	}
	internal(fmt.Sprintf("error unknown type:\"%v\"", t))
	panic("")
}

func reflectBasic(b types.BasicKind) reflect.Type {
	switch b {
	default:
		panic(internal("unknown basic type"))
	case types.Bool:
		return reflect.TypeOf(true)
	case types.Int:
		return reflect.TypeOf(int(1))
	case types.Int8:
		return reflect.TypeOf(int8(1))
	case types.Int16:
		return reflect.TypeOf(int16(1))
	case types.Int32:
		return reflect.TypeOf(int32(1))
	case types.Int64:
		return reflect.TypeOf(int64(1))
	case types.Uint:
		return reflect.TypeOf(uint(1))
	case types.Uint8:
		return reflect.TypeOf(uint8(1))
	case types.Uint16:
		return reflect.TypeOf(uint16(1))
	case types.Uint32:
		return reflect.TypeOf(uint32(1))
	case types.Uint64:
		return reflect.TypeOf(uint64(1))
	case types.Float32:
		return reflect.TypeOf(float32(1))
	case types.Float64:
		return reflect.TypeOf(float64(1))
	}
}

var bInstrData = OpDataType{INTEGER_OP, InstrData{signed: false, size: 1}, XMM_INVALID}
var f32InstrData = OpDataType{XMM_OP, InstrData{}, XMM_F32}
var f64InstrData = OpDataType{XMM_OP, InstrData{}, XMM_F64}

func GetIntegerOpDataType(signed bool, size uint) OpDataType {
	instrdata := OpDataType{
		INTEGER_OP,
		InstrData{signed: signed, size: size},
		XMM_INVALID}
	return instrdata

}

func GetOpDataType(t types.Type) OpDataType {
	if isBool(t) {
		return bInstrData
	}
	if isFloat32(t) {
		return f32InstrData
	} else if isFloat64(t) {
		return f64InstrData
	}
	if isComplex(t) {
		panic("complex32/64 unsupported")
	}

	if isBasic(t) {
		return GetIntegerOpDataType(signed(t), sizeof(t))
	} else {
		panic(internal(fmt.Sprintf("non basic type \"%v\"", t)))
	}

}

func regType(t types.Type) RegType {
	if isFloat(t) {
		return XMM_REG
	}
	return DATA_REG
}
<|endoftext|>


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

package main

import (
	"bufio"
	"encoding/json"
	"io"
	"os"
	"strings"
	"text/template"
)

var cmdList = &Command{
	UsageLine: "list [-e] [-f format] [-json] [packages]",
	Short:     "list packages",
	Long: `
List lists the packages named by the import paths, one per line.

The default output shows the package import path:

    code.google.com/p/google-api-go-client/books/v1
    code.google.com/p/goauth2/oauth
    code.google.com/p/sqlite

The -f flag specifies an alternate format for the list, using the
syntax of package template.  The default output is equivalent to -f
'{{.ImportPath}}'.  One extra template function is available, "join",
which calls strings.Join. The struct being passed to the template is:

    type Package struct {
        Dir        string // directory containing package sources
        ImportPath string // import path of package in dir
        Name       string // package name
        Doc        string // package documentation string
        Target     string // install path
        Goroot     bool   // is this package in the Go root?
        Standard   bool   // is this package part of the standard Go library?
        Stale      bool   // would 'go install' do anything for this package?
        Root       string // Go root or Go path dir containing this package

        // Source files
        GoFiles  []string     // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)
        CgoFiles []string     // .go sources files that import "C"
        CFiles   []string     // .c source files
        HFiles   []string     // .h source files
        SFiles   []string     // .s source files
        SysoFiles []string    // .syso object files to add to archive
        SwigFiles []string    // .swig files
        SwigCXXFiles []string // .swigcxx files

        // Cgo directives
        CgoCFLAGS    []string // cgo: flags for C compiler
        CgoLDFLAGS   []string // cgo: flags for linker
        CgoPkgConfig []string // cgo: pkg-config names

        // Dependency information
        Imports []string // import paths used by this package
        Deps    []string // all (recursively) imported dependencies

        // Error information
        Incomplete bool            // this package or a dependency has an error
        Error      *PackageError   // error loading package
        DepsErrors []*PackageError // errors loading dependencies

        TestGoFiles  []string // _test.go files in package
        TestImports  []string // imports from TestGoFiles
        XTestGoFiles []string // _test.go files outside package
        XTestImports []string // imports from XTestGoFiles
    }

The -json flag causes the package data to be printed in JSON format
instead of using the template format.

The -e flag changes the handling of erroneous packages, those that
cannot be found or are malformed.  By default, the list command
prints an error to standard error for each erroneous package and
omits the packages from consideration during the usual printing.
With the -e flag, the list command never prints errors to standard
error and instead processes the erroneous packages with the usual
printing.  Erroneous packages will have a non-empty ImportPath and
a non-nil Error field; other information may or may not be missing
(zeroed).

For more about specifying packages, see 'go help packages'.
	`,
}

func init() {
	cmdList.Run = runList // break init cycle
	cmdList.Flag.Var(buildCompiler{}, "compiler", "")
}

var listE = cmdList.Flag.Bool("e", false, "")
var listFmt = cmdList.Flag.String("f", "{{.ImportPath}}", "")
var listJson = cmdList.Flag.Bool("json", false, "")
var nl = []byte{'\n'}

func runList(cmd *Command, args []string) {
	out := newCountingWriter(os.Stdout)
	defer out.w.Flush()

	var do func(*Package)
	if *listJson {
		do = func(p *Package) {
			b, err := json.MarshalIndent(p, "", "\t")
			if err != nil {
				out.Flush()
				fatalf("%s", err)
			}
			out.Write(b)
			out.Write(nl)
		}
	} else {
		tmpl, err := template.New("main").Funcs(template.FuncMap{"join": strings.Join}).Parse(*listFmt)
		if err != nil {
			fatalf("%s", err)
		}
		do = func(p *Package) {
			out.Reset()
			if err := tmpl.Execute(out, p); err != nil {
				out.Flush()
				fatalf("%s", err)
			}
			if out.Count() > 0 {
				out.w.WriteRune('\n')
			}
		}
	}

	load := packages
	if *listE {
		load = packagesAndErrors
	}

	for _, pkg := range load(args) {
		do(pkg)
	}
}

// CountingWriter counts its data, so we can avoid appending a newline
// if there was no actual output.
type CountingWriter struct {
	w     *bufio.Writer
	count int64
}

func newCountingWriter(w io.Writer) *CountingWriter {
	return &CountingWriter{
		w: bufio.NewWriter(w),
	}
}

func (cw *CountingWriter) Write(p []byte) (n int, err error) {
	cw.count += int64(len(p))
	return cw.w.Write(p)
}

func (cw *CountingWriter) Flush() {
	cw.w.Flush()
}

func (cw *CountingWriter) Reset() {
	cw.count = 0
}

func (cw *CountingWriter) Count() int64 {
	return cw.count
}
<commit_msg>cmd/go: suppress extraneous newlines in list<commit_after>// Copyright 2011 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"bufio"
	"encoding/json"
	"io"
	"os"
	"strings"
	"text/template"
)

var cmdList = &Command{
	UsageLine: "list [-e] [-f format] [-json] [packages]",
	Short:     "list packages",
	Long: `
List lists the packages named by the import paths, one per line.

The default output shows the package import path:

    code.google.com/p/google-api-go-client/books/v1
    code.google.com/p/goauth2/oauth
    code.google.com/p/sqlite

The -f flag specifies an alternate format for the list, using the
syntax of package template.  The default output is equivalent to -f
'{{.ImportPath}}'.  One extra template function is available, "join",
which calls strings.Join. The struct being passed to the template is:

    type Package struct {
        Dir        string // directory containing package sources
        ImportPath string // import path of package in dir
        Name       string // package name
        Doc        string // package documentation string
        Target     string // install path
        Goroot     bool   // is this package in the Go root?
        Standard   bool   // is this package part of the standard Go library?
        Stale      bool   // would 'go install' do anything for this package?
        Root       string // Go root or Go path dir containing this package

        // Source files
        GoFiles  []string     // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)
        CgoFiles []string     // .go sources files that import "C"
        CFiles   []string     // .c source files
        HFiles   []string     // .h source files
        SFiles   []string     // .s source files
        SysoFiles []string    // .syso object files to add to archive
        SwigFiles []string    // .swig files
        SwigCXXFiles []string // .swigcxx files

        // Cgo directives
        CgoCFLAGS    []string // cgo: flags for C compiler
        CgoLDFLAGS   []string // cgo: flags for linker
        CgoPkgConfig []string // cgo: pkg-config names

        // Dependency information
        Imports []string // import paths used by this package
        Deps    []string // all (recursively) imported dependencies

        // Error information
        Incomplete bool            // this package or a dependency has an error
        Error      *PackageError   // error loading package
        DepsErrors []*PackageError // errors loading dependencies

        TestGoFiles  []string // _test.go files in package
        TestImports  []string // imports from TestGoFiles
        XTestGoFiles []string // _test.go files outside package
        XTestImports []string // imports from XTestGoFiles
    }

The -json flag causes the package data to be printed in JSON format
instead of using the template format.

The -e flag changes the handling of erroneous packages, those that
cannot be found or are malformed.  By default, the list command
prints an error to standard error for each erroneous package and
omits the packages from consideration during the usual printing.
With the -e flag, the list command never prints errors to standard
error and instead processes the erroneous packages with the usual
printing.  Erroneous packages will have a non-empty ImportPath and
a non-nil Error field; other information may or may not be missing
(zeroed).

For more about specifying packages, see 'go help packages'.
	`,
}

func init() {
	cmdList.Run = runList // break init cycle
	cmdList.Flag.Var(buildCompiler{}, "compiler", "")
}

var listE = cmdList.Flag.Bool("e", false, "")
var listFmt = cmdList.Flag.String("f", "{{.ImportPath}}", "")
var listJson = cmdList.Flag.Bool("json", false, "")
var nl = []byte{'\n'}

func runList(cmd *Command, args []string) {
	out := newTrackingWriter(os.Stdout)
	defer out.w.Flush()

	var do func(*Package)
	if *listJson {
		do = func(p *Package) {
			b, err := json.MarshalIndent(p, "", "\t")
			if err != nil {
				out.Flush()
				fatalf("%s", err)
			}
			out.Write(b)
			out.Write(nl)
		}
	} else {
		tmpl, err := template.New("main").Funcs(template.FuncMap{"join": strings.Join}).Parse(*listFmt)
		if err != nil {
			fatalf("%s", err)
		}
		do = func(p *Package) {
			if err := tmpl.Execute(out, p); err != nil {
				out.Flush()
				fatalf("%s", err)
			}
			if out.NeedNL() {
				out.Write([]byte{'\n'})
			}
		}
	}

	load := packages
	if *listE {
		load = packagesAndErrors
	}

	for _, pkg := range load(args) {
		do(pkg)
	}
}

// TrackingWriter tracks the last byte written on every write so
// we can avoid printing a newline if one was already written or
// if there is no output at all.
type TrackingWriter struct {
	w    *bufio.Writer
	last byte
}

func newTrackingWriter(w io.Writer) *TrackingWriter {
	return &TrackingWriter{
		w:    bufio.NewWriter(w),
		last: '\n',
	}
}

func (t *TrackingWriter) Write(p []byte) (n int, err error) {
	n, err = t.w.Write(p)
	if n > 0 {
		t.last = p[n-1]
	}
	return
}

func (t *TrackingWriter) Flush() {
	t.w.Flush()
}

func (t *TrackingWriter) NeedNL() bool {
	return t.last != '\n'
}
<|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.

/*
	Package fmt implements formatted I/O with functions analogous
	to C's printf and scanf.  The format 'verbs' are derived from C's but
	are simpler.

	Printing

	The verbs:

	General:
		%v	the value in a default format
			when printing structs, the plus flag (%+v) adds field names
		%#v	a Go-syntax representation of the value
		%T	a Go-syntax representation of the type of the value
		%%	a literal percent sign; consumes no value

	Boolean:
		%t	the word true or false
	Integer:
		%b	base 2
		%c	the character represented by the corresponding Unicode code point
		%d	base 10
		%o	base 8
		%q	a single-quoted character literal safely escaped with Go syntax.
		%x	base 16, with lower-case letters for a-f
		%X	base 16, with upper-case letters for A-F
		%U	Unicode format: U+1234; same as "U+%04X"
	Floating-point and complex constituents:
		%b	decimalless scientific notation with exponent a power of two,
			in the manner of strconv.FormatFloat with the 'b' format,
			e.g. -123456p-78
		%e	scientific notation, e.g. -1234.456e+78
		%E	scientific notation, e.g. -1234.456E+78
		%f	decimal point but no exponent, e.g. 123.456
		%F	synonym for %f
		%g	%e for large exponents, %f otherwise
		%G	%E for large exponents, %G otherwise
	String and slice of bytes:
		%s	the uninterpreted bytes of the string or slice
		%q	a double-quoted string safely escaped with Go syntax
		%x	base 16, lower-case, two characters per byte
		%X	base 16, upper-case, two characters per byte
	Pointer:
		%p	base 16 notation, with leading 0x

	There is no 'u' flag.  Integers are printed unsigned if they have unsigned type.
	Similarly, there is no need to specify the size of the operand (int8, int64).

	The default format for %v is:
		bool:                    %t
		int, int8 etc.:          %d
		uint, uint8 etc.:        %d, %x if printed with %#v
		float32, complex64, etc: %g
		string:                  %s
		chan:                    %p
		pointer:                 %p
	For compound objects, the elements are printed using these rules, recursively,
	laid out like this:
		struct:             {field0 field1 ...}
		array, slice:       [elem0  elem1 ...]
		maps:               map[key1:value1 key2:value2]
		pointer to above:   &{}, &[], &map[]

	Width is specified by an optional decimal number immediately following the verb.
	If absent, the width is whatever is necessary to represent the value.
	Precision is specified after the (optional) width by a period followed by a
	decimal number. If no period is present, a default precision is used.
	A period with no following number specifies a precision of zero.
	Examples:
		%f:    default width, default precision
		%9f    width 9, default precision
		%.2f   default width, precision 2
		%9.2f  width 9, precision 2
		%9.f   width 9, precision 0

	Width and precision are measured in units of Unicode code points,
	that is, runes. (This differs from C's printf where the
	units are always measured in bytes.) Either or both of the flags
	may be replaced with the character '*', causing their values to be
	obtained from the next operand, which must be of type int.

	For most values, width is the minimum number of runes to output,
	padding the formatted form with spaces if necessary.

	For strings, byte slices and byte arrays, however, precision
	limits the length of the input to be formatted (not the size of
	the output), truncating if necessary. Normally it is measured in
	runes, but for these types when formatted with the %x or %X format
	it is measured in bytes.

	For floating-point values, width sets the minimum width of the field and
	precision sets the number of places after the decimal, if appropriate,
	except that for %g/%G it sets the total number of digits. For example,
	given 123.45 the format %6.2f prints 123.45 while %.4g prints 123.5.
	The default precision for %e and %f is 6; for %g it is the smallest
	number of digits necessary to identify the value uniquely.

	For complex numbers, the width and precision apply to the two
	components independently and the result is parenthesized, so %f applied
	to 1.2+3.4i produces (1.200000+3.400000i).

	Other flags:
		+	always print a sign for numeric values;
			guarantee ASCII-only output for %q (%+q)
		-	pad with spaces on the right rather than the left (left-justify the field)
		#	alternate format: add leading 0 for octal (%#o), 0x for hex (%#x);
			0X for hex (%#X); suppress 0x for %p (%#p);
			for %q, print a raw (backquoted) string if strconv.CanBackquote
			returns true;
			write e.g. U+0078 'x' if the character is printable for %U (%#U).
		' '	(space) leave a space for elided sign in numbers (% d);
			put spaces between bytes printing strings or slices in hex (% x, % X)
		0	pad with leading zeros rather than spaces;
			for numbers, this moves the padding after the sign

	Flags are ignored by verbs that do not expect them.
	For example there is no alternate decimal format, so %#d and %d
	behave identically.

	For each Printf-like function, there is also a Print function
	that takes no format and is equivalent to saying %v for every
	operand.  Another variant Println inserts blanks between
	operands and appends a newline.

	Regardless of the verb, if an operand is an interface value,
	the internal concrete value is used, not the interface itself.
	Thus:
		var i interface{} = 23
		fmt.Printf("%v\n", i)
	will print 23.

	Except when printed using the verbs %T and %p, special
	formatting considerations apply for operands that implement
	certain interfaces. In order of application:

	1. If an operand implements the Formatter interface, it will
	be invoked. Formatter provides fine control of formatting.

	2. If the %v verb is used with the # flag (%#v) and the operand
	implements the GoStringer interface, that will be invoked.

	If the format (which is implicitly %v for Println etc.) is valid
	for a string (%s %q %v %x %X), the following two rules apply:

	3. If an operand implements the error interface, the Error method
	will be invoked to convert the object to a string, which will then
	be formatted as required by the verb (if any).

	4. If an operand implements method String() string, that method
	will be invoked to convert the object to a string, which will then
	be formatted as required by the verb (if any).

	For compound operands such as slices and structs, the format
	applies to the elements of each operand, recursively, not to the
	operand as a whole. Thus %q will quote each element of a slice
	of strings, and %6.2f will control formatting for each element
	of a floating-point array.

	To avoid recursion in cases such as
		type X string
		func (x X) String() string { return Sprintf("<%s>", x) }
	convert the value before recurring:
		func (x X) String() string { return Sprintf("<%s>", string(x)) }
	Infinite recursion can also be triggered by self-referential data
	structures, such as a slice that contains itself as an element, if
	that type has a String method. Such pathologies are rare, however,
	and the package does not protect against them.

	Explicit argument indexes:

	In Printf, Sprintf, and Fprintf, the default behavior is for each
	formatting verb to format successive arguments passed in the call.
	However, the notation [n] immediately before the verb indicates that the
	nth one-indexed argument is to be formatted instead. The same notation
	before a '*' for a width or precision selects the argument index holding
	the value. After processing a bracketed expression [n], arguments n+1,
	n+2, etc. will be processed unless otherwise directed.

	For example,
		fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
	will yield "22 11", while
		fmt.Sprintf("%[3]*.[2]*[1]f", 12.0, 2, 6),
	equivalent to
		fmt.Sprintf("%6.2f", 12.0),
	will yield " 12.00". Because an explicit index affects subsequent verbs,
	this notation can be used to print the same values multiple times
	by resetting the index for the first argument to be repeated:
		fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
	will yield "16 17 0x10 0x11".

	Format errors:

	If an invalid argument is given for a verb, such as providing
	a string to %d, the generated string will contain a
	description of the problem, as in these examples:

		Wrong type or unknown verb: %!verb(type=value)
			Printf("%d", hi):          %!d(string=hi)
		Too many arguments: %!(EXTRA type=value)
			Printf("hi", "guys"):      hi%!(EXTRA string=guys)
		Too few arguments: %!verb(MISSING)
			Printf("hi%d"):            hi %!d(MISSING)
		Non-int for width or precision: %!(BADWIDTH) or %!(BADPREC)
			Printf("%*s", 4.5, "hi"):  %!(BADWIDTH)hi
			Printf("%.*s", 4.5, "hi"): %!(BADPREC)hi
		Invalid or invalid use of argument index: %!(BADINDEX)
			Printf("%*[2]d", 7):       %!d(BADINDEX)
			Printf("%.[2]d", 7):       %!d(BADINDEX)

	All errors begin with the string "%!" followed sometimes
	by a single character (the verb) and end with a parenthesized
	description.

	If an Error or String method triggers a panic when called by a
	print routine, the fmt package reformats the error message
	from the panic, decorating it with an indication that it came
	through the fmt package.  For example, if a String method
	calls panic("bad"), the resulting formatted message will look
	like
		%!s(PANIC=bad)

	The %!s just shows the print verb in use when the failure
	occurred.

	Scanning

	An analogous set of functions scans formatted text to yield
	values.  Scan, Scanf and Scanln read from os.Stdin; Fscan,
	Fscanf and Fscanln read from a specified io.Reader; Sscan,
	Sscanf and Sscanln read from an argument string.  Scanln,
	Fscanln and Sscanln stop scanning at a newline and require that
	the items be followed by one; Scanf, Fscanf and Sscanf require
	newlines in the input to match newlines in the format; the other
	routines treat newlines as spaces.

	Scanf, Fscanf, and Sscanf parse the arguments according to a
	format string, analogous to that of Printf.  For example, %x
	will scan an integer as a hexadecimal number, and %v will scan
	the default representation format for the value.

	The formats behave analogously to those of Printf with the
	following exceptions:

		%p is not implemented
		%T is not implemented
		%e %E %f %F %g %G are all equivalent and scan any floating point or complex value
		%s and %v on strings scan a space-delimited token
		Flags # and + are not implemented.

	The familiar base-setting prefixes 0 (octal) and 0x
	(hexadecimal) are accepted when scanning integers without a
	format or with the %v verb.

	Width is interpreted in the input text (%5s means at most
	five runes of input will be read to scan a string) but there
	is no syntax for scanning with a precision (no %5.2f, just
	%5f).

	When scanning with a format, all non-empty runs of space
	characters (except newline) are equivalent to a single
	space in both the format and the input.  With that proviso,
	text in the format string must match the input text; scanning
	stops if it does not, with the return value of the function
	indicating the number of arguments scanned.

	In all the scanning functions, a carriage return followed
	immediately by a newline is treated as a plain newline
	(\r\n means the same as \n).

	In all the scanning functions, if an operand implements method
	Scan (that is, it implements the Scanner interface) that
	method will be used to scan the text for that operand.  Also,
	if the number of arguments scanned is less than the number of
	arguments provided, an error is returned.

	All arguments to be scanned must be either pointers to basic
	types or implementations of the Scanner interface.

	Note: Fscan etc. can read one character (rune) past the input
	they return, which means that a loop calling a scan routine
	may skip some of the input.  This is usually a problem only
	when there is no space between input values.  If the reader
	provided to Fscan implements ReadRune, that method will be used
	to read characters.  If the reader also implements UnreadRune,
	that method will be used to save the character and successive
	calls will not lose data.  To attach ReadRune and UnreadRune
	methods to a reader without that capability, use
	bufio.NewReader.
*/
package fmt
<commit_msg>fmt: fix one-letter typo in doc.go Stupid mistake in previous CL.<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.

/*
	Package fmt implements formatted I/O with functions analogous
	to C's printf and scanf.  The format 'verbs' are derived from C's but
	are simpler.

	Printing

	The verbs:

	General:
		%v	the value in a default format
			when printing structs, the plus flag (%+v) adds field names
		%#v	a Go-syntax representation of the value
		%T	a Go-syntax representation of the type of the value
		%%	a literal percent sign; consumes no value

	Boolean:
		%t	the word true or false
	Integer:
		%b	base 2
		%c	the character represented by the corresponding Unicode code point
		%d	base 10
		%o	base 8
		%q	a single-quoted character literal safely escaped with Go syntax.
		%x	base 16, with lower-case letters for a-f
		%X	base 16, with upper-case letters for A-F
		%U	Unicode format: U+1234; same as "U+%04X"
	Floating-point and complex constituents:
		%b	decimalless scientific notation with exponent a power of two,
			in the manner of strconv.FormatFloat with the 'b' format,
			e.g. -123456p-78
		%e	scientific notation, e.g. -1234.456e+78
		%E	scientific notation, e.g. -1234.456E+78
		%f	decimal point but no exponent, e.g. 123.456
		%F	synonym for %f
		%g	%e for large exponents, %f otherwise
		%G	%E for large exponents, %F otherwise
	String and slice of bytes:
		%s	the uninterpreted bytes of the string or slice
		%q	a double-quoted string safely escaped with Go syntax
		%x	base 16, lower-case, two characters per byte
		%X	base 16, upper-case, two characters per byte
	Pointer:
		%p	base 16 notation, with leading 0x

	There is no 'u' flag.  Integers are printed unsigned if they have unsigned type.
	Similarly, there is no need to specify the size of the operand (int8, int64).

	The default format for %v is:
		bool:                    %t
		int, int8 etc.:          %d
		uint, uint8 etc.:        %d, %x if printed with %#v
		float32, complex64, etc: %g
		string:                  %s
		chan:                    %p
		pointer:                 %p
	For compound objects, the elements are printed using these rules, recursively,
	laid out like this:
		struct:             {field0 field1 ...}
		array, slice:       [elem0  elem1 ...]
		maps:               map[key1:value1 key2:value2]
		pointer to above:   &{}, &[], &map[]

	Width is specified by an optional decimal number immediately following the verb.
	If absent, the width is whatever is necessary to represent the value.
	Precision is specified after the (optional) width by a period followed by a
	decimal number. If no period is present, a default precision is used.
	A period with no following number specifies a precision of zero.
	Examples:
		%f:    default width, default precision
		%9f    width 9, default precision
		%.2f   default width, precision 2
		%9.2f  width 9, precision 2
		%9.f   width 9, precision 0

	Width and precision are measured in units of Unicode code points,
	that is, runes. (This differs from C's printf where the
	units are always measured in bytes.) Either or both of the flags
	may be replaced with the character '*', causing their values to be
	obtained from the next operand, which must be of type int.

	For most values, width is the minimum number of runes to output,
	padding the formatted form with spaces if necessary.

	For strings, byte slices and byte arrays, however, precision
	limits the length of the input to be formatted (not the size of
	the output), truncating if necessary. Normally it is measured in
	runes, but for these types when formatted with the %x or %X format
	it is measured in bytes.

	For floating-point values, width sets the minimum width of the field and
	precision sets the number of places after the decimal, if appropriate,
	except that for %g/%G it sets the total number of digits. For example,
	given 123.45 the format %6.2f prints 123.45 while %.4g prints 123.5.
	The default precision for %e and %f is 6; for %g it is the smallest
	number of digits necessary to identify the value uniquely.

	For complex numbers, the width and precision apply to the two
	components independently and the result is parenthesized, so %f applied
	to 1.2+3.4i produces (1.200000+3.400000i).

	Other flags:
		+	always print a sign for numeric values;
			guarantee ASCII-only output for %q (%+q)
		-	pad with spaces on the right rather than the left (left-justify the field)
		#	alternate format: add leading 0 for octal (%#o), 0x for hex (%#x);
			0X for hex (%#X); suppress 0x for %p (%#p);
			for %q, print a raw (backquoted) string if strconv.CanBackquote
			returns true;
			write e.g. U+0078 'x' if the character is printable for %U (%#U).
		' '	(space) leave a space for elided sign in numbers (% d);
			put spaces between bytes printing strings or slices in hex (% x, % X)
		0	pad with leading zeros rather than spaces;
			for numbers, this moves the padding after the sign

	Flags are ignored by verbs that do not expect them.
	For example there is no alternate decimal format, so %#d and %d
	behave identically.

	For each Printf-like function, there is also a Print function
	that takes no format and is equivalent to saying %v for every
	operand.  Another variant Println inserts blanks between
	operands and appends a newline.

	Regardless of the verb, if an operand is an interface value,
	the internal concrete value is used, not the interface itself.
	Thus:
		var i interface{} = 23
		fmt.Printf("%v\n", i)
	will print 23.

	Except when printed using the verbs %T and %p, special
	formatting considerations apply for operands that implement
	certain interfaces. In order of application:

	1. If an operand implements the Formatter interface, it will
	be invoked. Formatter provides fine control of formatting.

	2. If the %v verb is used with the # flag (%#v) and the operand
	implements the GoStringer interface, that will be invoked.

	If the format (which is implicitly %v for Println etc.) is valid
	for a string (%s %q %v %x %X), the following two rules apply:

	3. If an operand implements the error interface, the Error method
	will be invoked to convert the object to a string, which will then
	be formatted as required by the verb (if any).

	4. If an operand implements method String() string, that method
	will be invoked to convert the object to a string, which will then
	be formatted as required by the verb (if any).

	For compound operands such as slices and structs, the format
	applies to the elements of each operand, recursively, not to the
	operand as a whole. Thus %q will quote each element of a slice
	of strings, and %6.2f will control formatting for each element
	of a floating-point array.

	To avoid recursion in cases such as
		type X string
		func (x X) String() string { return Sprintf("<%s>", x) }
	convert the value before recurring:
		func (x X) String() string { return Sprintf("<%s>", string(x)) }
	Infinite recursion can also be triggered by self-referential data
	structures, such as a slice that contains itself as an element, if
	that type has a String method. Such pathologies are rare, however,
	and the package does not protect against them.

	Explicit argument indexes:

	In Printf, Sprintf, and Fprintf, the default behavior is for each
	formatting verb to format successive arguments passed in the call.
	However, the notation [n] immediately before the verb indicates that the
	nth one-indexed argument is to be formatted instead. The same notation
	before a '*' for a width or precision selects the argument index holding
	the value. After processing a bracketed expression [n], arguments n+1,
	n+2, etc. will be processed unless otherwise directed.

	For example,
		fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
	will yield "22 11", while
		fmt.Sprintf("%[3]*.[2]*[1]f", 12.0, 2, 6),
	equivalent to
		fmt.Sprintf("%6.2f", 12.0),
	will yield " 12.00". Because an explicit index affects subsequent verbs,
	this notation can be used to print the same values multiple times
	by resetting the index for the first argument to be repeated:
		fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
	will yield "16 17 0x10 0x11".

	Format errors:

	If an invalid argument is given for a verb, such as providing
	a string to %d, the generated string will contain a
	description of the problem, as in these examples:

		Wrong type or unknown verb: %!verb(type=value)
			Printf("%d", hi):          %!d(string=hi)
		Too many arguments: %!(EXTRA type=value)
			Printf("hi", "guys"):      hi%!(EXTRA string=guys)
		Too few arguments: %!verb(MISSING)
			Printf("hi%d"):            hi %!d(MISSING)
		Non-int for width or precision: %!(BADWIDTH) or %!(BADPREC)
			Printf("%*s", 4.5, "hi"):  %!(BADWIDTH)hi
			Printf("%.*s", 4.5, "hi"): %!(BADPREC)hi
		Invalid or invalid use of argument index: %!(BADINDEX)
			Printf("%*[2]d", 7):       %!d(BADINDEX)
			Printf("%.[2]d", 7):       %!d(BADINDEX)

	All errors begin with the string "%!" followed sometimes
	by a single character (the verb) and end with a parenthesized
	description.

	If an Error or String method triggers a panic when called by a
	print routine, the fmt package reformats the error message
	from the panic, decorating it with an indication that it came
	through the fmt package.  For example, if a String method
	calls panic("bad"), the resulting formatted message will look
	like
		%!s(PANIC=bad)

	The %!s just shows the print verb in use when the failure
	occurred.

	Scanning

	An analogous set of functions scans formatted text to yield
	values.  Scan, Scanf and Scanln read from os.Stdin; Fscan,
	Fscanf and Fscanln read from a specified io.Reader; Sscan,
	Sscanf and Sscanln read from an argument string.  Scanln,
	Fscanln and Sscanln stop scanning at a newline and require that
	the items be followed by one; Scanf, Fscanf and Sscanf require
	newlines in the input to match newlines in the format; the other
	routines treat newlines as spaces.

	Scanf, Fscanf, and Sscanf parse the arguments according to a
	format string, analogous to that of Printf.  For example, %x
	will scan an integer as a hexadecimal number, and %v will scan
	the default representation format for the value.

	The formats behave analogously to those of Printf with the
	following exceptions:

		%p is not implemented
		%T is not implemented
		%e %E %f %F %g %G are all equivalent and scan any floating point or complex value
		%s and %v on strings scan a space-delimited token
		Flags # and + are not implemented.

	The familiar base-setting prefixes 0 (octal) and 0x
	(hexadecimal) are accepted when scanning integers without a
	format or with the %v verb.

	Width is interpreted in the input text (%5s means at most
	five runes of input will be read to scan a string) but there
	is no syntax for scanning with a precision (no %5.2f, just
	%5f).

	When scanning with a format, all non-empty runs of space
	characters (except newline) are equivalent to a single
	space in both the format and the input.  With that proviso,
	text in the format string must match the input text; scanning
	stops if it does not, with the return value of the function
	indicating the number of arguments scanned.

	In all the scanning functions, a carriage return followed
	immediately by a newline is treated as a plain newline
	(\r\n means the same as \n).

	In all the scanning functions, if an operand implements method
	Scan (that is, it implements the Scanner interface) that
	method will be used to scan the text for that operand.  Also,
	if the number of arguments scanned is less than the number of
	arguments provided, an error is returned.

	All arguments to be scanned must be either pointers to basic
	types or implementations of the Scanner interface.

	Note: Fscan etc. can read one character (rune) past the input
	they return, which means that a loop calling a scan routine
	may skip some of the input.  This is usually a problem only
	when there is no space between input values.  If the reader
	provided to Fscan implements ReadRune, that method will be used
	to read characters.  If the reader also implements UnreadRune,
	that method will be used to save the character and successive
	calls will not lose data.  To attach ReadRune and UnreadRune
	methods to a reader without that capability, use
	bufio.NewReader.
*/
package fmt
<|endoftext|>