<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.

// Helper functions to make constructing templates and sets easier.

package template

import (
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
)

// Functions and methods to parse a single template.

// Must is a helper that wraps a call to a function returning (*Template, os.Error)
// and panics if the error is non-nil. It is intended for use in variable initializations
// such as
//	var t = template.Must(template.Parse("text"))
func Must(t *Template, err os.Error) *Template {
	if err != nil {
		panic(err)
	}
	return t
}

// ParseFile creates a new Template and parses the template definition from
// the named file.  The template name is the base name of the file.
func ParseFile(filename string) (*Template, os.Error) {
	t := New(filepath.Base(filename))
	return t.ParseFile(filename)
}

// parseFileInSet creates a new Template and parses the template
// definition from the named file. The template name is the base name
// of the file. It also adds the template to the set. Function bindings are
// checked against those in the set.
func parseFileInSet(filename string, set *Set) (*Template, os.Error) {
	t := New(filepath.Base(filename))
	return t.parseFileInSet(filename, set)
}

// ParseFile reads the template definition from a file and parses it to
// construct an internal representation of the template for execution.
func (t *Template) ParseFile(filename string) (*Template, os.Error) {
	b, err := ioutil.ReadFile(filename)
	if err != nil {
		return t, err
	}
	return t.Parse(string(b))
}

// parseFileInSet is the same as ParseFile except that function bindings
// are checked against those in the set and the template is added
// to the set.
func (t *Template) parseFileInSet(filename string, set *Set) (*Template, os.Error) {
	b, err := ioutil.ReadFile(filename)
	if err != nil {
		return t, err
	}
	return t.ParseInSet(string(b), set)
}

// Functions and methods to parse a set.

// SetMust is a helper that wraps a call to a function returning (*Set, os.Error)
// and panics if the error is non-nil. It is intended for use in variable initializations
// such as
//	var s = template.SetMust(template.ParseSetFile("file"))
func SetMust(s *Set, err os.Error) *Set {
	if err != nil {
		panic(err)
	}
	return s
}

// ParseFile parses the named files into a set of named templates.
// Each file must be parseable by itself. Parsing stops if an error is
// encountered.
func (s *Set) ParseFile(filenames ...string) (*Set, os.Error) {
	for _, filename := range filenames {
		b, err := ioutil.ReadFile(filename)
		if err != nil {
			return s, err
		}
		_, err = s.Parse(string(b))
		if err != nil {
			return s, err
		}
	}
	return s, nil
}

// ParseSetFile creates a new Set and parses the set definition from the
// named files. Each file must be individually parseable.
func ParseSetFile(filenames ...string) (*Set, os.Error) {
	s := new(Set)
	for _, filename := range filenames {
		b, err := ioutil.ReadFile(filename)
		if err != nil {
			return s, err
		}
		_, err = s.Parse(string(b))
		if err != nil {
			return s, err
		}
	}
	return s, nil
}

// ParseFiles parses the set definition from the files identified by the
// pattern.  The pattern is processed by filepath.Glob and must match at
// least one file.
func (s *Set) ParseFiles(pattern string) (*Set, os.Error) {
	filenames, err := filepath.Glob(pattern)
	if err != nil {
		return s, err
	}
	if len(filenames) == 0 {
		return s, fmt.Errorf("pattern matches no files: %#q", pattern)
	}
	return s.ParseFile(filenames...)
}

// ParseSetFiles creates a new Set and parses the set definition from the
// files identified by the pattern. The pattern is processed by filepath.Glob
// and must match at least one file.
func ParseSetFiles(pattern string) (*Set, os.Error) {
	set, err := new(Set).ParseFiles(pattern)
	if err != nil {
		return set, err
	}
	return set, nil
}

// Functions and methods to parse stand-alone template files into a set.

// ParseTemplateFile parses the named template files and adds
// them to the set. Each template will named the base name of
// its file.
// Unlike with ParseFile, each file should be a stand-alone template
// definition suitable for Template.Parse (not Set.Parse); that is, the
// file does not contain {{define}} clauses. ParseTemplateFile is
// therefore equivalent to calling the ParseFile function to create
// individual templates, which are then added to the set.
// Each file must be parseable by itself. Parsing stops if an error is
// encountered.
func (s *Set) ParseTemplateFile(filenames ...string) (*Set, os.Error) {
	for _, filename := range filenames {
		_, err := parseFileInSet(filename, s)
		if err != nil {
			return s, err
		}
	}
	return s, nil
}

// ParseTemplateFiles parses the template files matched by the
// patern and adds them to the set. Each template will named
// the base name of its file.
// Unlike with ParseFiles, each file should be a stand-alone template
// definition suitable for Template.Parse (not Set.Parse); that is, the
// file does not contain {{define}} clauses. ParseTemplateFiles is
// therefore equivalent to calling the ParseFile function to create
// individual templates, which are then added to the set.
// Each file must be parseable by itself. Parsing stops if an error is
// encountered.
func (s *Set) ParseTemplateFiles(pattern string) (*Set, os.Error) {
	filenames, err := filepath.Glob(pattern)
	if err != nil {
		return s, err
	}
	for _, filename := range filenames {
		_, err := parseFileInSet(filename, s)
		if err != nil {
			return s, err
		}
	}
	return s, nil
}

// ParseTemplateFile creates a set by parsing the named files,
// each of which defines a single template. Each template will
// named the base name of its file.
// Unlike with ParseFile, each file should be a stand-alone template
// definition suitable for Template.Parse (not Set.Parse); that is, the
// file does not contain {{define}} clauses. ParseTemplateFile is
// therefore equivalent to calling the ParseFile function to create
// individual templates, which are then added to the set.
// Each file must be parseable by itself. Parsing stops if an error is
// encountered.
func ParseTemplateFile(filenames ...string) (*Set, os.Error) {
	set := new(Set)
	for _, filename := range filenames {
		t, err := ParseFile(filename)
		if err != nil {
			return set, err
		}
		if err := set.add(t); err != nil {
			return set, err
		}
	}
	return set, nil
}

// ParseTemplateFiles creates a set by parsing the files matched
// by the pattern, each of which defines a single template. Each
// template will named the base name of its file.
// Unlike with ParseFiles, each file should be a stand-alone template
// definition suitable for Template.Parse (not Set.Parse); that is, the
// file does not contain {{define}} clauses. ParseTemplateFiles is
// therefore equivalent to calling the ParseFile function to create
// individual templates, which are then added to the set.
// Each file must be parseable by itself. Parsing stops if an error is
// encountered.
func ParseTemplateFiles(pattern string) (*Set, os.Error) {
	set := new(Set)
	filenames, err := filepath.Glob(pattern)
	if err != nil {
		return set, err
	}
	for _, filename := range filenames {
		t, err := ParseFile(filename)
		if err != nil {
			return set, err
		}
		if err := set.add(t); err != nil {
			return set, err
		}
	}
	return set, nil
}
<commit_msg>exp/template: ensure that a valid Set is returned even on error.<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.

// Helper functions to make constructing templates and sets easier.

package template

import (
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
)

// Functions and methods to parse a single template.

// Must is a helper that wraps a call to a function returning (*Template, os.Error)
// and panics if the error is non-nil. It is intended for use in variable initializations
// such as
//	var t = template.Must(template.Parse("text"))
func Must(t *Template, err os.Error) *Template {
	if err != nil {
		panic(err)
	}
	return t
}

// ParseFile creates a new Template and parses the template definition from
// the named file.  The template name is the base name of the file.
func ParseFile(filename string) (*Template, os.Error) {
	t := New(filepath.Base(filename))
	return t.ParseFile(filename)
}

// parseFileInSet creates a new Template and parses the template
// definition from the named file. The template name is the base name
// of the file. It also adds the template to the set. Function bindings are
// checked against those in the set.
func parseFileInSet(filename string, set *Set) (*Template, os.Error) {
	t := New(filepath.Base(filename))
	return t.parseFileInSet(filename, set)
}

// ParseFile reads the template definition from a file and parses it to
// construct an internal representation of the template for execution.
func (t *Template) ParseFile(filename string) (*Template, os.Error) {
	b, err := ioutil.ReadFile(filename)
	if err != nil {
		return t, err
	}
	return t.Parse(string(b))
}

// parseFileInSet is the same as ParseFile except that function bindings
// are checked against those in the set and the template is added
// to the set.
func (t *Template) parseFileInSet(filename string, set *Set) (*Template, os.Error) {
	b, err := ioutil.ReadFile(filename)
	if err != nil {
		return t, err
	}
	return t.ParseInSet(string(b), set)
}

// Functions and methods to parse a set.

// SetMust is a helper that wraps a call to a function returning (*Set, os.Error)
// and panics if the error is non-nil. It is intended for use in variable initializations
// such as
//	var s = template.SetMust(template.ParseSetFile("file"))
func SetMust(s *Set, err os.Error) *Set {
	if err != nil {
		panic(err)
	}
	return s
}

// ParseFile parses the named files into a set of named templates.
// Each file must be parseable by itself. Parsing stops if an error is
// encountered.
func (s *Set) ParseFile(filenames ...string) (*Set, os.Error) {
	for _, filename := range filenames {
		b, err := ioutil.ReadFile(filename)
		if err != nil {
			return s, err
		}
		_, err = s.Parse(string(b))
		if err != nil {
			return s, err
		}
	}
	return s, nil
}

// ParseSetFile creates a new Set and parses the set definition from the
// named files. Each file must be individually parseable.
func ParseSetFile(filenames ...string) (*Set, os.Error) {
	s := new(Set)
	s.init()
	for _, filename := range filenames {
		b, err := ioutil.ReadFile(filename)
		if err != nil {
			return s, err
		}
		_, err = s.Parse(string(b))
		if err != nil {
			return s, err
		}
	}
	return s, nil
}

// ParseFiles parses the set definition from the files identified by the
// pattern.  The pattern is processed by filepath.Glob and must match at
// least one file.
func (s *Set) ParseFiles(pattern string) (*Set, os.Error) {
	filenames, err := filepath.Glob(pattern)
	if err != nil {
		return s, err
	}
	if len(filenames) == 0 {
		return s, fmt.Errorf("pattern matches no files: %#q", pattern)
	}
	return s.ParseFile(filenames...)
}

// ParseSetFiles creates a new Set and parses the set definition from the
// files identified by the pattern. The pattern is processed by filepath.Glob
// and must match at least one file.
func ParseSetFiles(pattern string) (*Set, os.Error) {
	set, err := new(Set).ParseFiles(pattern)
	if err != nil {
		return set, err
	}
	return set, nil
}

// Functions and methods to parse stand-alone template files into a set.

// ParseTemplateFile parses the named template files and adds
// them to the set. Each template will named the base name of
// its file.
// Unlike with ParseFile, each file should be a stand-alone template
// definition suitable for Template.Parse (not Set.Parse); that is, the
// file does not contain {{define}} clauses. ParseTemplateFile is
// therefore equivalent to calling the ParseFile function to create
// individual templates, which are then added to the set.
// Each file must be parseable by itself. Parsing stops if an error is
// encountered.
func (s *Set) ParseTemplateFile(filenames ...string) (*Set, os.Error) {
	for _, filename := range filenames {
		_, err := parseFileInSet(filename, s)
		if err != nil {
			return s, err
		}
	}
	return s, nil
}

// ParseTemplateFiles parses the template files matched by the
// patern and adds them to the set. Each template will named
// the base name of its file.
// Unlike with ParseFiles, each file should be a stand-alone template
// definition suitable for Template.Parse (not Set.Parse); that is, the
// file does not contain {{define}} clauses. ParseTemplateFiles is
// therefore equivalent to calling the ParseFile function to create
// individual templates, which are then added to the set.
// Each file must be parseable by itself. Parsing stops if an error is
// encountered.
func (s *Set) ParseTemplateFiles(pattern string) (*Set, os.Error) {
	filenames, err := filepath.Glob(pattern)
	if err != nil {
		return s, err
	}
	for _, filename := range filenames {
		_, err := parseFileInSet(filename, s)
		if err != nil {
			return s, err
		}
	}
	return s, nil
}

// ParseTemplateFile creates a set by parsing the named files,
// each of which defines a single template. Each template will
// named the base name of its file.
// Unlike with ParseFile, each file should be a stand-alone template
// definition suitable for Template.Parse (not Set.Parse); that is, the
// file does not contain {{define}} clauses. ParseTemplateFile is
// therefore equivalent to calling the ParseFile function to create
// individual templates, which are then added to the set.
// Each file must be parseable by itself. Parsing stops if an error is
// encountered.
func ParseTemplateFile(filenames ...string) (*Set, os.Error) {
	set := new(Set)
	set.init()
	for _, filename := range filenames {
		t, err := ParseFile(filename)
		if err != nil {
			return set, err
		}
		if err := set.add(t); err != nil {
			return set, err
		}
	}
	return set, nil
}

// ParseTemplateFiles creates a set by parsing the files matched
// by the pattern, each of which defines a single template. Each
// template will named the base name of its file.
// Unlike with ParseFiles, each file should be a stand-alone template
// definition suitable for Template.Parse (not Set.Parse); that is, the
// file does not contain {{define}} clauses. ParseTemplateFiles is
// therefore equivalent to calling the ParseFile function to create
// individual templates, which are then added to the set.
// Each file must be parseable by itself. Parsing stops if an error is
// encountered.
func ParseTemplateFiles(pattern string) (*Set, os.Error) {
	set := new(Set)
	set.init()
	filenames, err := filepath.Glob(pattern)
	if err != nil {
		return set, err
	}
	for _, filename := range filenames {
		t, err := ParseFile(filename)
		if err != nil {
			return set, err
		}
		if err := set.add(t); err != nil {
			return set, err
		}
	}
	return set, nil
}
<|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 net

import (
	"flag"
	"io"
	"syscall"
	"testing"
)

// If an IPv6 tunnel is running (see go/stubl), we can try dialing a real IPv6 address.
var ipv6 = flag.Bool("ipv6", false, "assume ipv6 tunnel is present")

// fd is already connected to the destination, port 80.
// Run an HTTP request to fetch the appropriate page.
func fetchGoogle(t *testing.T, fd Conn, network, addr string) {
	req := []byte("GET /intl/en/privacy.html HTTP/1.0\r\nHost: www.google.com\r\n\r\n")
	n, err := fd.Write(req)

	buf := make([]byte, 1000)
	n, err = io.ReadFull(fd, buf)

	if n < 1000 {
		t.Errorf("fetchGoogle: short HTTP read from %s %s - %v", network, addr, err)
		return
	}
}

func doDial(t *testing.T, network, addr string) {
	fd, err := Dial(network, "", addr)
	if err != nil {
		t.Errorf("Dial(%q, %q, %q) = _, %v", network, "", addr, err)
		return
	}
	fetchGoogle(t, fd, network, addr)
	fd.Close()
}

var googleaddrs = []string{
	"74.125.19.99:80",
	"www.google.com:80",
	"74.125.19.99:http",
	"www.google.com:http",
	"074.125.019.099:0080",
	"[::ffff:74.125.19.99]:80",
	"[::ffff:4a7d:1363]:80",
	"[0:0:0:0:0000:ffff:74.125.19.99]:80",
	"[0:0:0:0:000000:ffff:74.125.19.99]:80",
	"[0:0:0:0:0:ffff::74.125.19.99]:80",
	"[2001:4860:0:2001::68]:80", // ipv6.google.com; removed if ipv6 flag not set
}

func TestDialGoogle(t *testing.T) {
	// If no ipv6 tunnel, don't try the last address.
	if !*ipv6 {
		googleaddrs[len(googleaddrs)-1] = ""
	}

	for i := 0; i < len(googleaddrs); i++ {
		addr := googleaddrs[i]
		if addr == "" {
			continue
		}
		t.Logf("-- %s --", addr)
		doDial(t, "tcp", addr)
		if addr[0] != '[' {
			doDial(t, "tcp4", addr)

			if !preferIPv4 {
				// make sure preferIPv4 flag works.
				preferIPv4 = true
				syscall.SocketDisableIPv6 = true
				doDial(t, "tcp4", addr)
				syscall.SocketDisableIPv6 = false
				preferIPv4 = false
			}
		}

		// Only run tcp6 if the kernel will take it.
		if kernelSupportsIPv6() {
			doDial(t, "tcp6", addr)
		}
	}
}
<commit_msg>net: fix TestDialGoogle<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 net

import (
	"flag"
	"io"
	"syscall"
	"testing"
)

// If an IPv6 tunnel is running (see go/stubl), we can try dialing a real IPv6 address.
var ipv6 = flag.Bool("ipv6", false, "assume ipv6 tunnel is present")

// fd is already connected to the destination, port 80.
// Run an HTTP request to fetch the appropriate page.
func fetchGoogle(t *testing.T, fd Conn, network, addr string) {
	req := []byte("GET /intl/en/privacy/ HTTP/1.0\r\nHost: www.google.com\r\n\r\n")
	n, err := fd.Write(req)

	buf := make([]byte, 1000)
	n, err = io.ReadFull(fd, buf)

	if n < 1000 {
		t.Errorf("fetchGoogle: short HTTP read from %s %s - %v", network, addr, err)
		return
	}
}

func doDial(t *testing.T, network, addr string) {
	fd, err := Dial(network, "", addr)
	if err != nil {
		t.Errorf("Dial(%q, %q, %q) = _, %v", network, "", addr, err)
		return
	}
	fetchGoogle(t, fd, network, addr)
	fd.Close()
}

var googleaddrs = []string{
	"74.125.19.99:80",
	"www.google.com:80",
	"74.125.19.99:http",
	"www.google.com:http",
	"074.125.019.099:0080",
	"[::ffff:74.125.19.99]:80",
	"[::ffff:4a7d:1363]:80",
	"[0:0:0:0:0000:ffff:74.125.19.99]:80",
	"[0:0:0:0:000000:ffff:74.125.19.99]:80",
	"[0:0:0:0:0:ffff::74.125.19.99]:80",
	"[2001:4860:0:2001::68]:80", // ipv6.google.com; removed if ipv6 flag not set
}

func TestDialGoogle(t *testing.T) {
	// If no ipv6 tunnel, don't try the last address.
	if !*ipv6 {
		googleaddrs[len(googleaddrs)-1] = ""
	}

	for i := 0; i < len(googleaddrs); i++ {
		addr := googleaddrs[i]
		if addr == "" {
			continue
		}
		t.Logf("-- %s --", addr)
		doDial(t, "tcp", addr)
		if addr[0] != '[' {
			doDial(t, "tcp4", addr)

			if !preferIPv4 {
				// make sure preferIPv4 flag works.
				preferIPv4 = true
				syscall.SocketDisableIPv6 = true
				doDial(t, "tcp4", addr)
				syscall.SocketDisableIPv6 = false
				preferIPv4 = false
			}
		}

		// Only run tcp6 if the kernel will take it.
		if kernelSupportsIPv6() {
			doDial(t, "tcp6", addr)
		}
	}
}
<|endoftext|>


<commit_before>//   Copyright 2009 Joubin Houshyar
//
//   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 redis

// ----------------------------------------------------------------------------
// PROTOCOL SPEC
//
// Various other elements of the package use the artifacts of this file to
// negotiate the Redis protocol.
//
// Redis version: 1.n
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// Types
// ----------------------------------------------------------------------------

// Redis 'KeyType'
//
type KeyType byte;

// Known Redis key types
//
const (
	RT_NONE 	KeyType = iota;
	RT_STRING;
	RT_SET;
	RT_LIST;
	RT_ZSET;
)

// Returns KeyType by name
//
func GetKeyType (typename string) (keytype KeyType) {
	switch {
	case typename == "none": keytype =  RT_NONE;
	case typename == "string": keytype =  RT_STRING;
	case typename == "list": keytype =  RT_LIST;
	case typename == "set": keytype =  RT_SET;
	case typename == "zset": keytype =  RT_ZSET;
	}
	return;
}

// Not yet used -- TODO: decide if returning status (say for Set) for non error cases
// really buys us anything beyond (useless) consistency.
//
type Status bool;
const (
	OK 	 bool	= true;
	PONG 		= true;
	ERR 		= false;
)

// Request type defines the characteristic pattern of a cmd request
//
type RequestType int;
const (
	_ RequestType = iota;
	NO_ARG;
	KEY;
	KEY_KEY;
	KEY_NUM;
	KEY_SPEC;
	KEY_NUM_NUM;
	KEY_VALUE;
	KEY_IDX_VALUE;
	KEY_KEY_VALUE;
	KEY_CNT_VALUE;
	MULTI_KEY;
)

// Response type defines the various flavors of responses from Redis
// per its specification.

type ResponseType int;
const (
	VIRTUAL ResponseType = iota;
	BOOLEAN;
	NUMBER;
	STRING;
	STATUS;
	BULK;
	MULTI_BULK;
)

// Describes a given Redis command
//
type Command struct {
	Code string;
	ReqType RequestType;
	RespType ResponseType;
}

// The supported Command set, with one to one mapping to eponymous Redis command.
//
var (
	AUTH			Command = Command {"AUTH", KEY, 	STATUS};
 	PING			Command = Command {"PING", NO_ARG, 	STATUS};
 	QUIT			Command = Command {"QUIT", NO_ARG, 	VIRTUAL};
 	SET				Command = Command {"SET", KEY_VALUE, 	STATUS};
 	GET				Command = Command {"GET", KEY, 	BULK};
 	GETSET			Command = Command {"GETSET", KEY_VALUE, 	BULK};
 	MGET			Command = Command {"MGET", MULTI_KEY, 	MULTI_BULK};
 	SETNX			Command = Command {"SETNX", KEY_VALUE, 	BOOLEAN};
 	INCR			Command = Command {"INCR", KEY, 	NUMBER};
 	INCRBY			Command = Command {"INCRBY", KEY_NUM, 	NUMBER};
 	DECR			Command = Command {"DECR", KEY, 	NUMBER};
 	DECRBY			Command = Command {"DECRBY", KEY_NUM, 	NUMBER};
 	EXISTS			Command = Command {"EXISTS", KEY, 	BOOLEAN};
 	DEL				Command = Command {"DEL", KEY, 	BOOLEAN};
 	TYPE			Command = Command {"TYPE", KEY, 	STRING};
 	KEYS			Command = Command {"KEYS", KEY, 	BULK};
 	RANDOMKEY		Command = Command {"RANDOMKEY", NO_ARG, 	STRING};
 	RENAME			Command = Command {"RENAME", KEY_KEY, 	STATUS};
 	RENAMENX		Command = Command {"RENAMENX", KEY_KEY, 	BOOLEAN};
 	DBSIZE			Command = Command {"DBSIZE", NO_ARG, 	NUMBER};
 	EXPIRE			Command = Command {"EXPIRE", KEY_NUM, 	BOOLEAN};
 	TTL				Command = Command {"TTL", KEY, 	NUMBER};
 	RPUSH			Command = Command {"RPUSH", KEY_VALUE, 	STATUS};
 	LPUSH			Command = Command {"LPUSH", KEY_VALUE, 	STATUS};
 	LLEN			Command = Command {"LLEN", KEY, 	NUMBER};
 	LRANGE			Command = Command {"LRANGE", KEY_NUM_NUM, 	MULTI_BULK};
 	LTRIM			Command = Command {"LTRIM", KEY_NUM_NUM, 	STATUS};
 	LINDEX			Command = Command {"LINDEX", KEY_NUM, 	BULK};
 	LSET			Command = Command {"LSET", KEY_IDX_VALUE, 	STATUS};
 	LREM			Command = Command {"LREM", KEY_CNT_VALUE, 	NUMBER};
 	LPOP			Command = Command {"LPOP", KEY, 	BULK};
 	RPOP			Command = Command {"RPOP", KEY, 	BULK};
 	RPOPLPUSH		Command = Command {"RPOPLPUSH", KEY_VALUE, 	BULK};
 	SADD			Command = Command {"SADD", KEY_VALUE, 	BOOLEAN};
 	SREM			Command = Command {"SREM", KEY_VALUE, 	BOOLEAN};
 	SCARD			Command = Command {"SCARD", KEY, 	NUMBER};
 	SISMEMBER		Command = Command {"SISMEMBER", KEY_VALUE, 	BOOLEAN};
 	SINTER			Command = Command {"SINTER", MULTI_KEY, 	MULTI_BULK};
 	SINTERSTORE		Command = Command {"SINTERSTORE", MULTI_KEY, 	STATUS};
 	SUNION			Command = Command {"SUNION", MULTI_KEY, 	MULTI_BULK};
 	SUNIONSTORE		Command = Command {"SUNIONSTORE", MULTI_KEY, 	STATUS};
 	SDIFF			Command = Command {"SDIFF", MULTI_KEY, 	MULTI_BULK};
 	SDIFFSTORE		Command = Command {"SDIFFSTORE", MULTI_KEY, 	STATUS};
 	SMEMBERS		Command = Command {"SMEMBERS", KEY, 	MULTI_BULK};
 	SMOVE			Command = Command {"SMOVE", KEY_KEY_VALUE, 	BOOLEAN};
 	SRANDMEMBER		Command = Command {"SRANDMEMBER", KEY, 	BULK};
 	ZADD			Command = Command {"ZADD", KEY_IDX_VALUE, 	BOOLEAN};
 	ZREM			Command = Command {"ZREM", KEY_VALUE, 	BOOLEAN};
 	ZCARD			Command = Command {"ZCARD", KEY, 	NUMBER};
 	ZSCORE			Command = Command {"ZSCORE", KEY_VALUE, 	BULK};
 	ZRANGE			Command = Command {"ZRANGE", KEY_NUM_NUM, 	MULTI_BULK};
 	ZREVRANGE		Command = Command {"ZREVRANGE", KEY_NUM_NUM, 	MULTI_BULK};
 	ZRANGEBYSCORE	Command = Command {"ZRANGEBYSCORE", KEY_NUM_NUM, 	MULTI_BULK};
 	SELECT			Command = Command {"SELECT", KEY, 	STATUS};
 	FLUSHDB			Command = Command {"FLUSHDB", NO_ARG, 	STATUS};
 	FLUSHALL		Command = Command {"FLUSHALL", NO_ARG, 	STATUS};
 	MOVE			Command = Command {"MOVE", KEY_NUM, 	BOOLEAN};
 	SORT			Command = Command {"SORT", KEY_SPEC, 	MULTI_BULK};
 	SAVE			Command = Command {"SAVE", NO_ARG, 	STATUS};
 	BGSAVE			Command = Command {"BGSAVE", NO_ARG, 	STATUS};
 	LASTSAVE		Command = Command {"LASTSAVE", NO_ARG, 	NUMBER};
 	SHUTDOWN		Command = Command {"SHUTDOWN", NO_ARG, 	VIRTUAL};
 	INFO			Command = Command {"INFO", NO_ARG, 	BULK};
 	MONITOR			Command = Command {"MONITOR", NO_ARG, 	VIRTUAL};
 )

<commit_msg>Tested against latest (03/23/2010) Go release.  Fixed minor const bool issue in specifications.go.<commit_after>//   Copyright 2009 Joubin Houshyar
//
//   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 redis

// ----------------------------------------------------------------------------
// PROTOCOL SPEC
//
// Various other elements of the package use the artifacts of this file to
// negotiate the Redis protocol.
//
// Redis version: 1.n
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// Types
// ----------------------------------------------------------------------------

// Redis 'KeyType'
//
type KeyType byte;

// Known Redis key types
//
const (
	RT_NONE 	KeyType = iota;
	RT_STRING;
	RT_SET;
	RT_LIST;
	RT_ZSET;
)

// Returns KeyType by name
//
func GetKeyType (typename string) (keytype KeyType) {
	switch {
	case typename == "none": keytype =  RT_NONE;
	case typename == "string": keytype =  RT_STRING;
	case typename == "list": keytype =  RT_LIST;
	case typename == "set": keytype =  RT_SET;
	case typename == "zset": keytype =  RT_ZSET;
	}
	return;
}

// Not yet used -- TODO: decide if returning status (say for Set) for non error cases
// really buys us anything beyond (useless) consistency.
//
type Status bool;
const (
	OK			= true;
	PONG 		= true;
	ERR 		= false;
)

// Request type defines the characteristic pattern of a cmd request
//
type RequestType int;
const (
	_ RequestType = iota;
	NO_ARG;
	KEY;
	KEY_KEY;
	KEY_NUM;
	KEY_SPEC;
	KEY_NUM_NUM;
	KEY_VALUE;
	KEY_IDX_VALUE;
	KEY_KEY_VALUE;
	KEY_CNT_VALUE;
	MULTI_KEY;
)

// Response type defines the various flavors of responses from Redis
// per its specification.

type ResponseType int;
const (
	VIRTUAL ResponseType = iota;
	BOOLEAN;
	NUMBER;
	STRING;
	STATUS;
	BULK;
	MULTI_BULK;
)

// Describes a given Redis command
//
type Command struct {
	Code string;
	ReqType RequestType;
	RespType ResponseType;
}

// The supported Command set, with one to one mapping to eponymous Redis command.
//
var (
	AUTH			Command = Command {"AUTH", KEY, 	STATUS};
 	PING			Command = Command {"PING", NO_ARG, 	STATUS};
 	QUIT			Command = Command {"QUIT", NO_ARG, 	VIRTUAL};
 	SET				Command = Command {"SET", KEY_VALUE, 	STATUS};
 	GET				Command = Command {"GET", KEY, 	BULK};
 	GETSET			Command = Command {"GETSET", KEY_VALUE, 	BULK};
 	MGET			Command = Command {"MGET", MULTI_KEY, 	MULTI_BULK};
 	SETNX			Command = Command {"SETNX", KEY_VALUE, 	BOOLEAN};
 	INCR			Command = Command {"INCR", KEY, 	NUMBER};
 	INCRBY			Command = Command {"INCRBY", KEY_NUM, 	NUMBER};
 	DECR			Command = Command {"DECR", KEY, 	NUMBER};
 	DECRBY			Command = Command {"DECRBY", KEY_NUM, 	NUMBER};
 	EXISTS			Command = Command {"EXISTS", KEY, 	BOOLEAN};
 	DEL				Command = Command {"DEL", KEY, 	BOOLEAN};
 	TYPE			Command = Command {"TYPE", KEY, 	STRING};
 	KEYS			Command = Command {"KEYS", KEY, 	BULK};
 	RANDOMKEY		Command = Command {"RANDOMKEY", NO_ARG, 	STRING};
 	RENAME			Command = Command {"RENAME", KEY_KEY, 	STATUS};
 	RENAMENX		Command = Command {"RENAMENX", KEY_KEY, 	BOOLEAN};
 	DBSIZE			Command = Command {"DBSIZE", NO_ARG, 	NUMBER};
 	EXPIRE			Command = Command {"EXPIRE", KEY_NUM, 	BOOLEAN};
 	TTL				Command = Command {"TTL", KEY, 	NUMBER};
 	RPUSH			Command = Command {"RPUSH", KEY_VALUE, 	STATUS};
 	LPUSH			Command = Command {"LPUSH", KEY_VALUE, 	STATUS};
 	LLEN			Command = Command {"LLEN", KEY, 	NUMBER};
 	LRANGE			Command = Command {"LRANGE", KEY_NUM_NUM, 	MULTI_BULK};
 	LTRIM			Command = Command {"LTRIM", KEY_NUM_NUM, 	STATUS};
 	LINDEX			Command = Command {"LINDEX", KEY_NUM, 	BULK};
 	LSET			Command = Command {"LSET", KEY_IDX_VALUE, 	STATUS};
 	LREM			Command = Command {"LREM", KEY_CNT_VALUE, 	NUMBER};
 	LPOP			Command = Command {"LPOP", KEY, 	BULK};
 	RPOP			Command = Command {"RPOP", KEY, 	BULK};
 	RPOPLPUSH		Command = Command {"RPOPLPUSH", KEY_VALUE, 	BULK};
 	SADD			Command = Command {"SADD", KEY_VALUE, 	BOOLEAN};
 	SREM			Command = Command {"SREM", KEY_VALUE, 	BOOLEAN};
 	SCARD			Command = Command {"SCARD", KEY, 	NUMBER};
 	SISMEMBER		Command = Command {"SISMEMBER", KEY_VALUE, 	BOOLEAN};
 	SINTER			Command = Command {"SINTER", MULTI_KEY, 	MULTI_BULK};
 	SINTERSTORE		Command = Command {"SINTERSTORE", MULTI_KEY, 	STATUS};
 	SUNION			Command = Command {"SUNION", MULTI_KEY, 	MULTI_BULK};
 	SUNIONSTORE		Command = Command {"SUNIONSTORE", MULTI_KEY, 	STATUS};
 	SDIFF			Command = Command {"SDIFF", MULTI_KEY, 	MULTI_BULK};
 	SDIFFSTORE		Command = Command {"SDIFFSTORE", MULTI_KEY, 	STATUS};
 	SMEMBERS		Command = Command {"SMEMBERS", KEY, 	MULTI_BULK};
 	SMOVE			Command = Command {"SMOVE", KEY_KEY_VALUE, 	BOOLEAN};
 	SRANDMEMBER		Command = Command {"SRANDMEMBER", KEY, 	BULK};
 	ZADD			Command = Command {"ZADD", KEY_IDX_VALUE, 	BOOLEAN};
 	ZREM			Command = Command {"ZREM", KEY_VALUE, 	BOOLEAN};
 	ZCARD			Command = Command {"ZCARD", KEY, 	NUMBER};
 	ZSCORE			Command = Command {"ZSCORE", KEY_VALUE, 	BULK};
 	ZRANGE			Command = Command {"ZRANGE", KEY_NUM_NUM, 	MULTI_BULK};
 	ZREVRANGE		Command = Command {"ZREVRANGE", KEY_NUM_NUM, 	MULTI_BULK};
 	ZRANGEBYSCORE	Command = Command {"ZRANGEBYSCORE", KEY_NUM_NUM, 	MULTI_BULK};
 	SELECT			Command = Command {"SELECT", KEY, 	STATUS};
 	FLUSHDB			Command = Command {"FLUSHDB", NO_ARG, 	STATUS};
 	FLUSHALL		Command = Command {"FLUSHALL", NO_ARG, 	STATUS};
 	MOVE			Command = Command {"MOVE", KEY_NUM, 	BOOLEAN};
 	SORT			Command = Command {"SORT", KEY_SPEC, 	MULTI_BULK};
 	SAVE			Command = Command {"SAVE", NO_ARG, 	STATUS};
 	BGSAVE			Command = Command {"BGSAVE", NO_ARG, 	STATUS};
 	LASTSAVE		Command = Command {"LASTSAVE", NO_ARG, 	NUMBER};
 	SHUTDOWN		Command = Command {"SHUTDOWN", NO_ARG, 	VIRTUAL};
 	INFO			Command = Command {"INFO", NO_ARG, 	BULK};
 	MONITOR			Command = Command {"MONITOR", NO_ARG, 	VIRTUAL};
 )

<|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.

// +build akaros

package syscall

import (
	"unsafe"
	"runtime/parlib"
)

type SysProcAttr struct {
	Chroot     string      // Chroot.
	Credential *Credential // Credential.
	Ptrace     bool        // Enable tracing.
	Setsid     bool        // Create session.
	Setpgid    bool        // Set process group ID to new pid (SYSV setpgrp)
	Setctty    bool        // Set controlling terminal to fd Ctty (only meaningful if Setsid is set)
	Noctty     bool        // Detach fd 0 from controlling terminal
	Ctty       int         // Controlling TTY fd (Linux only)
	Pdeathsig  Signal      // Signal that the process will get when its parent dies (Linux only)
}

// Fork, dup fd onto 0..len(fd), and exec(argv0, argvv, envv) in child.
// If a dup or exec fails, write the errno error to pipe.
// (Pipe is close-on-exec so if exec succeeds, it will be closed.)
// In the child, this function must not acquire any locks, because
// they might have been locked at the time of the fork.  This means
// no rescheduling, no malloc calls, and no new stack segments.
// The calls to RawSyscall are okay because they are assembly
// functions that do not grow the stack.
func forkAndExecInChild(argv0 *byte, argv0len int, argv, envv []*byte, chroot, dir *byte, attr *ProcAttr, sys *SysProcAttr, pipe int) (pid int, err error) {
	// Declare all variables at top in case any
	// declarations require heap allocation (e.g., err1).
	var (
		r1     uintptr
		err1   error
	)
	// The pipe is meant to be used by the child of the fork.
	// The runtime code checks error return and pipe.
	// The pipe is not applicable to Akaros. Just close it.
	RawSyscall(SYS_CLOSE, uintptr(pipe), uintptr(0), uintptr(0))
	// Make sure we aren't passing invalid arguments for Akaros (we should
	// probably support these some day though...)
	if chroot != nil {
		return 0, NewAkaError(EMORON, "Akaros does not support passing 'chroot' to forkAndExecInChild")
	}
	if dir != nil {
		return 0, NewAkaError(EMORON, "Akaros does not support passing 'dir' to forkAndExecInChild")
	}

	// Set up arguments for proc_create
	__cmd := uintptr(unsafe.Pointer(argv0))
	pi, _ := parlib.ProcinfoPackArgs(argv, envv)
    __cmdlen := uintptr(argv0len)
	__pi := uintptr(unsafe.Pointer(&pi))

	// Call proc create.
	r1, _, err1 = RawSyscall6(SYS_PROC_CREATE, __cmd, __cmdlen, __pi, parlib.PROC_DUP_FGRP, 0, 0)
	if err1 != nil {
		return 0, err1
	}
	child := int(r1)

	// Proc create succeeded, now run it!
	r1, _, err1 = RawSyscall(SYS_PROC_RUN, r1, 0, 0)
	if err1 != nil {
		return 0, err1
	}

	// Return the child pid
	return child, nil
}

// Try to open a pipe with O_CLOEXEC set on both file descriptors.
func forkExecPipe(p []int) (err error) {
	err = Pipe(p, O_CLOEXEC)
	return
}
<commit_msg>Don't PROC_DUP_FGRP, instead SYS_DUP_FDS_TO<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.

// +build akaros

package syscall

import (
	"bytes"
	"encoding/binary"
	"unsafe"
	"runtime/parlib"
)

type SysProcAttr struct {
	Chroot     string      // Chroot.
	Credential *Credential // Credential.
	Ptrace     bool        // Enable tracing.
	Setsid     bool        // Create session.
	Setpgid    bool        // Set process group ID to new pid (SYSV setpgrp)
	Setctty    bool        // Set controlling terminal to fd Ctty (only meaningful if Setsid is set)
	Noctty     bool        // Detach fd 0 from controlling terminal
	Ctty       int         // Controlling TTY fd (Linux only)
	Pdeathsig  Signal      // Signal that the process will get when its parent dies (Linux only)
}

// Fork, dup fd onto 0..len(fd), and exec(argv0, argvv, envv) in child.
// If a dup or exec fails, write the errno error to pipe.
// (Pipe is close-on-exec so if exec succeeds, it will be closed.)
// In the child, this function must not acquire any locks, because
// they might have been locked at the time of the fork.  This means
// no rescheduling, no malloc calls, and no new stack segments.
// The calls to RawSyscall are okay because they are assembly
// functions that do not grow the stack.
func forkAndExecInChild(argv0 *byte, argv0len int, argv, envv []*byte, chroot, dir *byte, attr *ProcAttr, sys *SysProcAttr, pipe int) (pid int, err error) {
	// Declare all variables at top in case any
	// declarations require heap allocation (e.g., err1).
	var (
		r1     uintptr
		err1   error
	)
	// The pipe is meant to be used by the child of the fork.
	// The runtime code checks error return and pipe.
	// The pipe is not applicable to Akaros. Just close it.
	RawSyscall(SYS_CLOSE, uintptr(pipe), uintptr(0), uintptr(0))

	// Make sure we aren't passing invalid arguments for Akaros (we should
	// probably support these some day though...)
	if chroot != nil {
		return 0, NewAkaError(EMORON, "Akaros does not support passing 'chroot' to forkAndExecInChild")
	}
	if dir != nil {
		return 0, NewAkaError(EMORON, "Akaros does not support passing 'dir' to forkAndExecInChild")
	}

	// Set up arguments for proc_create
	__cmd := uintptr(unsafe.Pointer(argv0))
	pi, _ := parlib.ProcinfoPackArgs(argv, envv)
    __cmdlen := uintptr(argv0len)
	__pi := uintptr(unsafe.Pointer(&pi))

	// Buffer below is of objects mathcing this ptototype
	// type cfdmap struct {
	//      parentfd int32
	//      childfd int32
	//      ok int32
	// }
	cfdm := new(bytes.Buffer)
	for i,f := range(attr.Files) {
		binary.Write(cfdm, binary.LittleEndian, int32(f))
		binary.Write(cfdm, binary.LittleEndian, int32(i))
		binary.Write(cfdm, binary.LittleEndian, int32(-1))
	}
	__cfdm := uintptr(unsafe.Pointer(&(cfdm.Bytes()[0])))

	// Call proc create.
	r1, _, err1 = RawSyscall6(SYS_PROC_CREATE, __cmd, __cmdlen, __pi, 0, 0, 0)
	if err1 != nil {
		return 0, err1
	}
	child := r1

	r1, _, err1 = RawSyscall(SYS_DUP_FDS_TO, uintptr(child),
	                         __cfdm, uintptr(len(attr.Files)))
	if err1 != nil {
		return 0, err1
	}

	// Proc create succeeded, now run it!
	r1, _, err1 = RawSyscall(SYS_PROC_RUN, child, 0, 0)
	if err1 != nil {
		return 0, err1
	}

	// Return the child pid
	return int(child), nil
}

// Try to open a pipe with O_CLOEXEC set on both file descriptors.
func forkExecPipe(p []int) (err error) {
	err = Pipe(p, O_CLOEXEC)
	return
}
<|endoftext|>


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

// +build linux darwin freebsd netbsd openbsd

package syscall_test

import (
	"flag"
	"fmt"
	"io/ioutil"
	"net"
	"os"
	"os/exec"
	"syscall"
	"testing"
	"time"
)

// TestPassFD tests passing a file descriptor over a Unix socket.
//
// This test involved both a parent and child process. The parent
// process is invoked as a normal test, with "go test", which then
// runs the child process by running the current test binary with args
// "-test.run=^TestPassFD$" and an environment variable used to signal
// that the test should become the child process instead.
func TestPassFD(t *testing.T) {
	if os.Getenv("GO_WANT_HELPER_PROCESS") == "1" {
		passFDChild()
		return
	}

	tempDir, err := ioutil.TempDir("", "TestPassFD")
	if err != nil {
		t.Fatal(err)
	}
	defer os.RemoveAll(tempDir)

	fds, err := syscall.Socketpair(syscall.AF_LOCAL, syscall.SOCK_STREAM, 0)
	if err != nil {
		t.Fatalf("Socketpair: %v", err)
	}
	defer syscall.Close(fds[0])
	defer syscall.Close(fds[1])
	writeFile := os.NewFile(uintptr(fds[0]), "child-writes")
	readFile := os.NewFile(uintptr(fds[1]), "parent-reads")
	defer writeFile.Close()
	defer readFile.Close()

	cmd := exec.Command(os.Args[0], "-test.run=^TestPassFD$", "--", tempDir)
	cmd.Env = append([]string{"GO_WANT_HELPER_PROCESS=1"}, os.Environ()...)
	cmd.ExtraFiles = []*os.File{writeFile}

	out, err := cmd.CombinedOutput()
	if len(out) > 0 || err != nil {
		t.Fatalf("child process: %q, %v", out, err)
	}

	c, err := net.FileConn(readFile)
	if err != nil {
		t.Fatalf("FileConn: %v", err)
	}
	defer c.Close()

	uc, ok := c.(*net.UnixConn)
	if !ok {
		t.Fatalf("unexpected FileConn type; expected UnixConn, got %T", c)
	}

	buf := make([]byte, 32) // expect 1 byte
	oob := make([]byte, 32) // expect 24 bytes
	closeUnix := time.AfterFunc(5*time.Second, func() {
		t.Logf("timeout reading from unix socket")
		uc.Close()
	})
	_, oobn, _, _, err := uc.ReadMsgUnix(buf, oob)
	closeUnix.Stop()

	scms, err := syscall.ParseSocketControlMessage(oob[:oobn])
	if err != nil {
		t.Fatalf("ParseSocketControlMessage: %v", err)
	}
	if len(scms) != 1 {
		t.Fatalf("expected 1 SocketControlMessage; got scms = %#v", scms)
	}
	scm := scms[0]
	gotFds, err := syscall.ParseUnixRights(&scm)
	if err != nil {
		t.Fatalf("syscall.ParseUnixRights: %v", err)
	}
	if len(gotFds) != 1 {
		t.Fatalf("wanted 1 fd; got %#v", gotFds)
	}

	f := os.NewFile(uintptr(gotFds[0]), "fd-from-child")
	defer f.Close()

	got, err := ioutil.ReadAll(f)
	want := "Hello from child process!\n"
	if string(got) != want {
		t.Errorf("child process ReadAll: %q, %v; want %q", got, err, want)
	}
}

// passFDChild is the child process used by TestPassFD.
func passFDChild() {
	defer os.Exit(0)

	// Look for our fd. It should be fd 3, but we work around an fd leak
	// bug here (http://golang.org/issue/2603) to let it be elsewhere.
	var uc *net.UnixConn
	for fd := uintptr(3); fd <= 10; fd++ {
		f := os.NewFile(fd, "unix-conn")
		var ok bool
		netc, _ := net.FileConn(f)
		uc, ok = netc.(*net.UnixConn)
		if ok {
			break
		}
	}
	if uc == nil {
		fmt.Println("failed to find unix fd")
		return
	}

	// Make a file f to send to our parent process on uc.
	// We make it in tempDir, which our parent will clean up.
	flag.Parse()
	tempDir := flag.Arg(0)
	f, err := ioutil.TempFile(tempDir, "")
	if err != nil {
		fmt.Printf("TempFile: %v", err)
		return
	}

	f.Write([]byte("Hello from child process!\n"))
	f.Seek(0, 0)

	rights := syscall.UnixRights(int(f.Fd()))
	dummyByte := []byte("x")
	n, oobn, err := uc.WriteMsgUnix(dummyByte, rights, nil)
	if err != nil {
		fmt.Printf("WriteMsgUnix: %v", err)
		return
	}
	if n != 1 || oobn != len(rights) {
		fmt.Printf("WriteMsgUnix = %d, %d; want 1, %d", n, oobn, len(rights))
		return
	}
}

// TestUnixRightsRoundtrip tests that UnixRights, ParseSocketControlMessage,
// and ParseUnixRights are able to successfully round-trip lists of file descriptors.
func TestUnixRightsRoundtrip(t *testing.T) {
	testCases := [...][][]int{
		{{42}},
		{{1, 2}},
		{{3, 4, 5}},
		{{}},
		{{1, 2}, {3, 4, 5}, {}, {7}},
	}
	for _, testCase := range testCases {
		b := []byte{}
		var n int
		for _, fds := range testCase {
			// Last assignment to n wins
			n = len(b) + syscall.CmsgLen(4*len(fds))
			b = append(b, syscall.UnixRights(fds...)...)
		}
		// Truncate b
		b = b[:n]

		scms, err := syscall.ParseSocketControlMessage(b)
		if err != nil {
			t.Fatalf("ParseSocketControlMessage: %v", err)
		}
		if len(scms) != len(testCase) {
			t.Fatalf("expected %v SocketControlMessage; got scms = %#v", len(testCase), scms)
		}
		for i, scm := range scms {
			gotFds, err := syscall.ParseUnixRights(&scm)
			if err != nil {
				t.Fatalf("ParseUnixRights: %v", err)
			}
			wantFds := testCase[i]
			if len(gotFds) != len(wantFds) {
				t.Fatalf("expected %v fds, got %#v", len(wantFds), gotFds)
			}
			for j, fd := range gotFds {
				if fd != wantFds[j] {
					t.Fatalf("expected fd %v, got %v", wantFds[j], fd)
				}
			}
		}
	}
}
<commit_msg>syscall: disable TestPassFD on openbsd<commit_after>// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build linux darwin freebsd netbsd openbsd

package syscall_test

import (
	"flag"
	"fmt"
	"io/ioutil"
	"net"
	"os"
	"os/exec"
	"runtime"
	"syscall"
	"testing"
	"time"
)

// TestPassFD tests passing a file descriptor over a Unix socket.
//
// This test involved both a parent and child process. The parent
// process is invoked as a normal test, with "go test", which then
// runs the child process by running the current test binary with args
// "-test.run=^TestPassFD$" and an environment variable used to signal
// that the test should become the child process instead.
func TestPassFD(t *testing.T) {
	if runtime.GOOS == "openbsd" {
		t.Skip("issue 4956")
	}
	if os.Getenv("GO_WANT_HELPER_PROCESS") == "1" {
		passFDChild()
		return
	}

	tempDir, err := ioutil.TempDir("", "TestPassFD")
	if err != nil {
		t.Fatal(err)
	}
	defer os.RemoveAll(tempDir)

	fds, err := syscall.Socketpair(syscall.AF_LOCAL, syscall.SOCK_STREAM, 0)
	if err != nil {
		t.Fatalf("Socketpair: %v", err)
	}
	defer syscall.Close(fds[0])
	defer syscall.Close(fds[1])
	writeFile := os.NewFile(uintptr(fds[0]), "child-writes")
	readFile := os.NewFile(uintptr(fds[1]), "parent-reads")
	defer writeFile.Close()
	defer readFile.Close()

	cmd := exec.Command(os.Args[0], "-test.run=^TestPassFD$", "--", tempDir)
	cmd.Env = append([]string{"GO_WANT_HELPER_PROCESS=1"}, os.Environ()...)
	cmd.ExtraFiles = []*os.File{writeFile}

	out, err := cmd.CombinedOutput()
	if len(out) > 0 || err != nil {
		t.Fatalf("child process: %q, %v", out, err)
	}

	c, err := net.FileConn(readFile)
	if err != nil {
		t.Fatalf("FileConn: %v", err)
	}
	defer c.Close()

	uc, ok := c.(*net.UnixConn)
	if !ok {
		t.Fatalf("unexpected FileConn type; expected UnixConn, got %T", c)
	}

	buf := make([]byte, 32) // expect 1 byte
	oob := make([]byte, 32) // expect 24 bytes
	closeUnix := time.AfterFunc(5*time.Second, func() {
		t.Logf("timeout reading from unix socket")
		uc.Close()
	})
	_, oobn, _, _, err := uc.ReadMsgUnix(buf, oob)
	closeUnix.Stop()

	scms, err := syscall.ParseSocketControlMessage(oob[:oobn])
	if err != nil {
		t.Fatalf("ParseSocketControlMessage: %v", err)
	}
	if len(scms) != 1 {
		t.Fatalf("expected 1 SocketControlMessage; got scms = %#v", scms)
	}
	scm := scms[0]
	gotFds, err := syscall.ParseUnixRights(&scm)
	if err != nil {
		t.Fatalf("syscall.ParseUnixRights: %v", err)
	}
	if len(gotFds) != 1 {
		t.Fatalf("wanted 1 fd; got %#v", gotFds)
	}

	f := os.NewFile(uintptr(gotFds[0]), "fd-from-child")
	defer f.Close()

	got, err := ioutil.ReadAll(f)
	want := "Hello from child process!\n"
	if string(got) != want {
		t.Errorf("child process ReadAll: %q, %v; want %q", got, err, want)
	}
}

// passFDChild is the child process used by TestPassFD.
func passFDChild() {
	defer os.Exit(0)

	// Look for our fd. It should be fd 3, but we work around an fd leak
	// bug here (http://golang.org/issue/2603) to let it be elsewhere.
	var uc *net.UnixConn
	for fd := uintptr(3); fd <= 10; fd++ {
		f := os.NewFile(fd, "unix-conn")
		var ok bool
		netc, _ := net.FileConn(f)
		uc, ok = netc.(*net.UnixConn)
		if ok {
			break
		}
	}
	if uc == nil {
		fmt.Println("failed to find unix fd")
		return
	}

	// Make a file f to send to our parent process on uc.
	// We make it in tempDir, which our parent will clean up.
	flag.Parse()
	tempDir := flag.Arg(0)
	f, err := ioutil.TempFile(tempDir, "")
	if err != nil {
		fmt.Printf("TempFile: %v", err)
		return
	}

	f.Write([]byte("Hello from child process!\n"))
	f.Seek(0, 0)

	rights := syscall.UnixRights(int(f.Fd()))
	dummyByte := []byte("x")
	n, oobn, err := uc.WriteMsgUnix(dummyByte, rights, nil)
	if err != nil {
		fmt.Printf("WriteMsgUnix: %v", err)
		return
	}
	if n != 1 || oobn != len(rights) {
		fmt.Printf("WriteMsgUnix = %d, %d; want 1, %d", n, oobn, len(rights))
		return
	}
}

// TestUnixRightsRoundtrip tests that UnixRights, ParseSocketControlMessage,
// and ParseUnixRights are able to successfully round-trip lists of file descriptors.
func TestUnixRightsRoundtrip(t *testing.T) {
	testCases := [...][][]int{
		{{42}},
		{{1, 2}},
		{{3, 4, 5}},
		{{}},
		{{1, 2}, {3, 4, 5}, {}, {7}},
	}
	for _, testCase := range testCases {
		b := []byte{}
		var n int
		for _, fds := range testCase {
			// Last assignment to n wins
			n = len(b) + syscall.CmsgLen(4*len(fds))
			b = append(b, syscall.UnixRights(fds...)...)
		}
		// Truncate b
		b = b[:n]

		scms, err := syscall.ParseSocketControlMessage(b)
		if err != nil {
			t.Fatalf("ParseSocketControlMessage: %v", err)
		}
		if len(scms) != len(testCase) {
			t.Fatalf("expected %v SocketControlMessage; got scms = %#v", len(testCase), scms)
		}
		for i, scm := range scms {
			gotFds, err := syscall.ParseUnixRights(&scm)
			if err != nil {
				t.Fatalf("ParseUnixRights: %v", err)
			}
			wantFds := testCase[i]
			if len(gotFds) != len(wantFds) {
				t.Fatalf("expected %v fds, got %#v", len(wantFds), gotFds)
			}
			for j, fd := range gotFds {
				if fd != wantFds[j] {
					t.Fatalf("expected fd %v, got %v", wantFds[j], fd)
				}
			}
		}
	}
}
<|endoftext|>


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

/*
Package html implements an HTML5-compliant tokenizer and parser.
INCOMPLETE.

Tokenization is done by creating a Tokenizer for an io.Reader r. It is the
caller's responsibility to ensure that r provides UTF-8 encoded HTML.

	z := html.NewTokenizer(r)

Given a Tokenizer z, the HTML is tokenized by repeatedly calling z.Next(),
which parses the next token and returns its type, or an error:

	for {
		tt := z.Next()
		if tt == html.ErrorToken {
			// ...
			return ...
		}
		// Process the current token.
	}

There are two APIs for retrieving the current token. The high-level API is to
call Token; the low-level API is to call Text or TagName / TagAttr. Both APIs
allow optionally calling Raw after Next but before Token, Text, TagName, or
TagAttr. In EBNF notation, the valid call sequence per token is:

	Next {Raw} [ Token | Text | TagName {TagAttr} ]

Token returns an independent data structure that completely describes a token.
Entities (such as "<") are unescaped, tag names and attribute keys are
lower-cased, and attributes are collected into a []Attribute. For example:

	for {
		if z.Next() == html.ErrorToken {
			// Returning io.EOF indicates success.
			return z.Error()
		}
		emitToken(z.Token())
	}

The low-level API performs fewer allocations and copies, but the contents of
the []byte values returned by Text, TagName and TagAttr may change on the next
call to Next. For example, to extract an HTML page's anchor text:

	depth := 0
	for {
		tt := z.Next()
		switch tt {
		case ErrorToken:
			return z.Error()
		case TextToken:
			if depth > 0 {
				// emitBytes should copy the []byte it receives,
				// if it doesn't process it immediately.
				emitBytes(z.Text())
			}
		case StartTagToken, EndTagToken:
			tn, _ := z.TagName()
			if len(tn) == 1 && tn[0] == 'a' {
				if tt == StartTag {
					depth++
				} else {
					depth--
				}
			}
		}
	}

Parsing is done by calling Parse with an io.Reader, which returns the root of
the parse tree (the document element) as a *Node. It is the caller's
responsibility to ensure that the Reader provides UTF-8 encoded HTML. For
example, to process each anchor node in depth-first order:

	doc, err := html.Parse(r)
	if err != nil {
		// ...
	}
	var f func(*html.Node)
	f = func(n *html.Node) {
		if n.Type == html.ElementNode && n.Data == "a" {
			// Do something with n...
		}
		for _, c := range n.Child {
			f(c)
		}
	}
	f(doc)

The relevant specifications include:
http://www.whatwg.org/specs/web-apps/current-work/multipage/syntax.html and
http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html
*/
package html

// The tokenization algorithm implemented by this package is not a line-by-line
// transliteration of the relatively verbose state-machine in the WHATWG
// specification. A more direct approach is used instead, where the program
// counter implies the state, such as whether it is tokenizing a tag or a text
// node. Specification compliance is verified by checking expected and actual
// outputs over a test suite rather than aiming for algorithmic fidelity.

// TODO(nigeltao): Does a DOM API belong in this package or a separate one?
// TODO(nigeltao): How does parsing interact with a JavaScript engine?
<commit_msg>html: fix typo in package docs.<commit_after>// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

/*
Package html implements an HTML5-compliant tokenizer and parser.
INCOMPLETE.

Tokenization is done by creating a Tokenizer for an io.Reader r. It is the
caller's responsibility to ensure that r provides UTF-8 encoded HTML.

	z := html.NewTokenizer(r)

Given a Tokenizer z, the HTML is tokenized by repeatedly calling z.Next(),
which parses the next token and returns its type, or an error:

	for {
		tt := z.Next()
		if tt == html.ErrorToken {
			// ...
			return ...
		}
		// Process the current token.
	}

There are two APIs for retrieving the current token. The high-level API is to
call Token; the low-level API is to call Text or TagName / TagAttr. Both APIs
allow optionally calling Raw after Next but before Token, Text, TagName, or
TagAttr. In EBNF notation, the valid call sequence per token is:

	Next {Raw} [ Token | Text | TagName {TagAttr} ]

Token returns an independent data structure that completely describes a token.
Entities (such as "<") are unescaped, tag names and attribute keys are
lower-cased, and attributes are collected into a []Attribute. For example:

	for {
		if z.Next() == html.ErrorToken {
			// Returning io.EOF indicates success.
			return z.Error()
		}
		emitToken(z.Token())
	}

The low-level API performs fewer allocations and copies, but the contents of
the []byte values returned by Text, TagName and TagAttr may change on the next
call to Next. For example, to extract an HTML page's anchor text:

	depth := 0
	for {
		tt := z.Next()
		switch tt {
		case ErrorToken:
			return z.Error()
		case TextToken:
			if depth > 0 {
				// emitBytes should copy the []byte it receives,
				// if it doesn't process it immediately.
				emitBytes(z.Text())
			}
		case StartTagToken, EndTagToken:
			tn, _ := z.TagName()
			if len(tn) == 1 && tn[0] == 'a' {
				if tt == StartTagToken {
					depth++
				} else {
					depth--
				}
			}
		}
	}

Parsing is done by calling Parse with an io.Reader, which returns the root of
the parse tree (the document element) as a *Node. It is the caller's
responsibility to ensure that the Reader provides UTF-8 encoded HTML. For
example, to process each anchor node in depth-first order:

	doc, err := html.Parse(r)
	if err != nil {
		// ...
	}
	var f func(*html.Node)
	f = func(n *html.Node) {
		if n.Type == html.ElementNode && n.Data == "a" {
			// Do something with n...
		}
		for _, c := range n.Child {
			f(c)
		}
	}
	f(doc)

The relevant specifications include:
http://www.whatwg.org/specs/web-apps/current-work/multipage/syntax.html and
http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html
*/
package html

// The tokenization algorithm implemented by this package is not a line-by-line
// transliteration of the relatively verbose state-machine in the WHATWG
// specification. A more direct approach is used instead, where the program
// counter implies the state, such as whether it is tokenizing a tag or a text
// node. Specification compliance is verified by checking expected and actual
// outputs over a test suite rather than aiming for algorithmic fidelity.

// TODO(nigeltao): Does a DOM API belong in this package or a separate one?
// TODO(nigeltao): How does parsing interact with a JavaScript engine?
<|endoftext|>


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

package net

import "os"

// Dial connects to the remote address raddr on the network net.
// If the string laddr is not empty, it is used as the local address
// for the connection.
//
// Known networks are "tcp", "tcp4" (IPv4-only), "tcp6" (IPv6-only),
// "udp", "udp4" (IPv4-only), "udp6" (IPv6-only), "ip", "ip4"
// (IPv4-only) and "ip6" IPv6-only).
//
// For IP networks, addresses have the form host:port.  If host is
// a literal IPv6 address, it must be enclosed in square brackets.
//
// Examples:
//	Dial("tcp", "", "12.34.56.78:80")
//	Dial("tcp", "", "google.com:80")
//	Dial("tcp", "", "[de:ad:be:ef::ca:fe]:80")
//	Dial("tcp", "127.0.0.1:123", "127.0.0.1:88")
//
func Dial(net, laddr, raddr string) (c Conn, err os.Error) {
	switch prefixBefore(net, ':') {
	case "tcp", "tcp4", "tcp6":
		var la, ra *TCPAddr
		if laddr != "" {
			if la, err = ResolveTCPAddr(laddr); err != nil {
				goto Error
			}
		}
		if raddr != "" {
			if ra, err = ResolveTCPAddr(raddr); err != nil {
				goto Error
			}
		}
		c, err := DialTCP(net, la, ra)
		if err != nil {
			return nil, err
		}
		return c, nil
	case "udp", "udp4", "udp6":
		var la, ra *UDPAddr
		if laddr != "" {
			if la, err = ResolveUDPAddr(laddr); err != nil {
				goto Error
			}
		}
		if raddr != "" {
			if ra, err = ResolveUDPAddr(raddr); err != nil {
				goto Error
			}
		}
		c, err := DialUDP(net, la, ra)
		if err != nil {
			return nil, err
		}
		return c, nil
	case "unix", "unixgram":
		var la, ra *UnixAddr
		if raddr != "" {
			if ra, err = ResolveUnixAddr(net, raddr); err != nil {
				goto Error
			}
		}
		if laddr != "" {
			if la, err = ResolveUnixAddr(net, laddr); err != nil {
				goto Error
			}
		}
		c, err = DialUnix(net, la, ra)
		if err != nil {
			return nil, err
		}
		return c, nil
	case "ip", "ip4", "ip6":
		var la, ra *IPAddr
		if laddr != "" {
			if la, err = ResolveIPAddr(laddr); err != nil {
				goto Error
			}
		}
		if raddr != "" {
			if ra, err = ResolveIPAddr(raddr); err != nil {
				goto Error
			}
		}
		c, err := DialIP(net, la, ra)
		if err != nil {
			return nil, err
		}
		return c, nil

	}
	err = UnknownNetworkError(net)
Error:
	return nil, &OpError{"dial", net + " " + raddr, nil, err}
}

// Listen announces on the local network address laddr.
// The network string net must be a stream-oriented
// network: "tcp", "tcp4", "tcp6", or "unix".
func Listen(net, laddr string) (l Listener, err os.Error) {
	switch net {
	case "tcp", "tcp4", "tcp6":
		var la *TCPAddr
		if laddr != "" {
			if la, err = ResolveTCPAddr(laddr); err != nil {
				return nil, err
			}
		}
		l, err := ListenTCP(net, la)
		if err != nil {
			return nil, err
		}
		return l, nil
	case "unix":
		var la *UnixAddr
		if laddr != "" {
			if la, err = ResolveUnixAddr(net, laddr); err != nil {
				return nil, err
			}
		}
		l, err := ListenUnix(net, la)
		if err != nil {
			return nil, err
		}
		return l, nil
	}
	return nil, UnknownNetworkError(net)
}

// ListenPacket announces on the local network address laddr.
// The network string net must be a packet-oriented network:
// "udp", "udp4", "udp6", or "unixgram".
func ListenPacket(net, laddr string) (c PacketConn, err os.Error) {
	switch prefixBefore(net, ':') {
	case "udp", "udp4", "udp6":
		var la *UDPAddr
		if laddr != "" {
			if la, err = ResolveUDPAddr(laddr); err != nil {
				return nil, err
			}
		}
		c, err := ListenUDP(net, la)
		if err != nil {
			return nil, err
		}
		return c, nil
	case "unixgram":
		var la *UnixAddr
		if laddr != "" {
			if la, err = ResolveUnixAddr(net, laddr); err != nil {
				return nil, err
			}
		}
		c, err := DialUnix(net, la, nil)
		if err != nil {
			return nil, err
		}
		return c, nil
	case "ip", "ip4", "ip6":
		var la *IPAddr
		if laddr != "" {
			if la, err = ResolveIPAddr(laddr); err != nil {
				return nil, err
			}
		}
		c, err := ListenIP(net, la)
		if err != nil {
			return nil, err
		}
		return c, nil
	}
	return nil, UnknownNetworkError(net)
}
<commit_msg>net: fix comment on Dial to mention unix/unixgram.<commit_after>// Copyright 2010 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package net

import "os"

// Dial connects to the remote address raddr on the network net.
// If the string laddr is not empty, it is used as the local address
// for the connection.
//
// Known networks are "tcp", "tcp4" (IPv4-only), "tcp6" (IPv6-only),
// "udp", "udp4" (IPv4-only), "udp6" (IPv6-only), "ip", "ip4"
// (IPv4-only), "ip6" (IPv6-only), "unix" and "unixgram".
//
// For IP networks, addresses have the form host:port.  If host is
// a literal IPv6 address, it must be enclosed in square brackets.
//
// Examples:
//	Dial("tcp", "", "12.34.56.78:80")
//	Dial("tcp", "", "google.com:80")
//	Dial("tcp", "", "[de:ad:be:ef::ca:fe]:80")
//	Dial("tcp", "127.0.0.1:123", "127.0.0.1:88")
//
func Dial(net, laddr, raddr string) (c Conn, err os.Error) {
	switch prefixBefore(net, ':') {
	case "tcp", "tcp4", "tcp6":
		var la, ra *TCPAddr
		if laddr != "" {
			if la, err = ResolveTCPAddr(laddr); err != nil {
				goto Error
			}
		}
		if raddr != "" {
			if ra, err = ResolveTCPAddr(raddr); err != nil {
				goto Error
			}
		}
		c, err := DialTCP(net, la, ra)
		if err != nil {
			return nil, err
		}
		return c, nil
	case "udp", "udp4", "udp6":
		var la, ra *UDPAddr
		if laddr != "" {
			if la, err = ResolveUDPAddr(laddr); err != nil {
				goto Error
			}
		}
		if raddr != "" {
			if ra, err = ResolveUDPAddr(raddr); err != nil {
				goto Error
			}
		}
		c, err := DialUDP(net, la, ra)
		if err != nil {
			return nil, err
		}
		return c, nil
	case "unix", "unixgram":
		var la, ra *UnixAddr
		if raddr != "" {
			if ra, err = ResolveUnixAddr(net, raddr); err != nil {
				goto Error
			}
		}
		if laddr != "" {
			if la, err = ResolveUnixAddr(net, laddr); err != nil {
				goto Error
			}
		}
		c, err = DialUnix(net, la, ra)
		if err != nil {
			return nil, err
		}
		return c, nil
	case "ip", "ip4", "ip6":
		var la, ra *IPAddr
		if laddr != "" {
			if la, err = ResolveIPAddr(laddr); err != nil {
				goto Error
			}
		}
		if raddr != "" {
			if ra, err = ResolveIPAddr(raddr); err != nil {
				goto Error
			}
		}
		c, err := DialIP(net, la, ra)
		if err != nil {
			return nil, err
		}
		return c, nil

	}
	err = UnknownNetworkError(net)
Error:
	return nil, &OpError{"dial", net + " " + raddr, nil, err}
}

// Listen announces on the local network address laddr.
// The network string net must be a stream-oriented
// network: "tcp", "tcp4", "tcp6", or "unix".
func Listen(net, laddr string) (l Listener, err os.Error) {
	switch net {
	case "tcp", "tcp4", "tcp6":
		var la *TCPAddr
		if laddr != "" {
			if la, err = ResolveTCPAddr(laddr); err != nil {
				return nil, err
			}
		}
		l, err := ListenTCP(net, la)
		if err != nil {
			return nil, err
		}
		return l, nil
	case "unix":
		var la *UnixAddr
		if laddr != "" {
			if la, err = ResolveUnixAddr(net, laddr); err != nil {
				return nil, err
			}
		}
		l, err := ListenUnix(net, la)
		if err != nil {
			return nil, err
		}
		return l, nil
	}
	return nil, UnknownNetworkError(net)
}

// ListenPacket announces on the local network address laddr.
// The network string net must be a packet-oriented network:
// "udp", "udp4", "udp6", or "unixgram".
func ListenPacket(net, laddr string) (c PacketConn, err os.Error) {
	switch prefixBefore(net, ':') {
	case "udp", "udp4", "udp6":
		var la *UDPAddr
		if laddr != "" {
			if la, err = ResolveUDPAddr(laddr); err != nil {
				return nil, err
			}
		}
		c, err := ListenUDP(net, la)
		if err != nil {
			return nil, err
		}
		return c, nil
	case "unixgram":
		var la *UnixAddr
		if laddr != "" {
			if la, err = ResolveUnixAddr(net, laddr); err != nil {
				return nil, err
			}
		}
		c, err := DialUnix(net, la, nil)
		if err != nil {
			return nil, err
		}
		return c, nil
	case "ip", "ip4", "ip6":
		var la *IPAddr
		if laddr != "" {
			if la, err = ResolveIPAddr(laddr); err != nil {
				return nil, err
			}
		}
		c, err := ListenIP(net, la)
		if err != nil {
			return nil, err
		}
		return c, nil
	}
	return nil, UnknownNetworkError(net)
}
<|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 xml

import (
	"bytes"
	"io"
	"os"
	"reflect"
	"strings"
	"unicode"
)

// BUG(rsc): Mapping between XML elements and data structures is inherently flawed:
// an XML element is an order-dependent collection of anonymous
// values, while a data structure is an order-independent collection
// of named values.
// See package json for a textual representation more suitable
// to data structures.

// Unmarshal parses an XML element from r and uses the
// reflect library to fill in an arbitrary struct, slice, or string
// pointed at by val.  Well-formed data that does not fit
// into val is discarded.
//
// For example, given these definitions:
//
//	type Email struct {
//		Where string "attr";
//		Addr string;
//	}
//
//	type Result struct {
//		XMLName xml.Name "result";
//		Name string;
//		Phone string;
//		Email []Email;
//	}
//
//	var result = Result{ "name", "phone", nil }
//
// unmarshalling the XML input
//
//	<result>
//		<email where="home">
//			<addr>gre@example.com</addr>
//		</email>
//		<email where='work'>
//			<addr>gre@work.com</addr>
//		</email>
//		<name>Grace R. Emlin</name>
//		<address>123 Main Street</address>
//	</result>
//
// via Unmarshal(r, &result) is equivalent to assigning
//
//	r = Result{
//		xml.Name{"", "result"},
//		"Grace R. Emlin",	// name
//		"phone",	// no phone given
//		[]Email{
//			Email{ "home", "gre@example.com" },
//			Email{ "work", "gre@work.com" }
//		}
//	}
//
// Note that the field r.Phone has not been modified and
// that the XML <address> element was discarded.
//
// Because Unmarshal uses the reflect package, it can only
// assign to upper case fields.  Unmarshal uses a case-insensitive
// comparison to match XML element names to struct field names.
//
// Unmarshal maps an XML element to a struct using the following rules:
//
//   * If the struct has a field named XMLName of type xml.Name,
//      Unmarshal records the element name in that field.
//
//   * If the XMLName field has an associated tag string of the form
//      "tag" or "namespace-URL tag", the XML element must have
//      the given tag (and, optionally, name space) or else Unmarshal
//      returns an error.
//
//   * If the XML element has an attribute whose name matches a
//      struct field of type string with tag "attr", Unmarshal records
//      the attribute value in that field.
//
//   * If the XML element contains character data, that data is
//      accumulated in the first struct field that has tag "chardata".
//      The struct field may have type []byte or string.
//      If there is no such field, the character data is discarded.
//
//   * If the XML element contains a sub-element whose name
//      matches a struct field whose tag is neither "attr" nor "chardata",
//      Unmarshal maps the sub-element to that struct field.
//      Otherwise, if the struct has a field named Any, unmarshal
//      maps the sub-element to that struct field.
//
// Unmarshal maps an XML element to a string or []byte by saving the
// concatenation of that elements character data in the string or []byte.
//
// Unmarshal maps an XML element to a slice by extending the length
// of the slice and mapping the element to the newly created value.
//
// Unmarshal maps an XML element to a bool by setting the bool to true.
//
// Unmarshal maps an XML element to an xml.Name by recording the
// element name.
//
// Unmarshal maps an XML element to a pointer by setting the pointer
// to a freshly allocated value and then mapping the element to that value.
//
func Unmarshal(r io.Reader, val interface{}) os.Error {
	v, ok := reflect.NewValue(val).(*reflect.PtrValue)
	if !ok {
		return os.NewError("non-pointer passed to Unmarshal")
	}
	p := NewParser(r)
	elem := v.Elem()
	err := p.unmarshal(elem, nil)
	if err != nil {
		return err
	}
	return nil
}

// An UnmarshalError represents an error in the unmarshalling process.
type UnmarshalError string

func (e UnmarshalError) String() string { return string(e) }

// The Parser's Unmarshal method is like xml.Unmarshal
// except that it can be passed a pointer to the initial start element,
// useful when a client reads some raw XML tokens itself
// but also defers to Unmarshal for some elements.
// Passing a nil start element indicates that Unmarshal should
// read the token stream to find the start element.
func (p *Parser) Unmarshal(val interface{}, start *StartElement) os.Error {
	v, ok := reflect.NewValue(val).(*reflect.PtrValue)
	if !ok {
		return os.NewError("non-pointer passed to Unmarshal")
	}
	return p.unmarshal(v.Elem(), start)
}

// fieldName strips invalid characters from an XML name
// to create a valid Go struct name.  It also converts the
// name to lower case letters.
func fieldName(original string) string {
	return strings.Map(
		func(x int) int {
			if unicode.IsDigit(x) || unicode.IsLetter(x) {
				return unicode.ToLower(x)
			}
			return -1
		},
		original)
}

// Unmarshal a single XML element into val.
func (p *Parser) unmarshal(val reflect.Value, start *StartElement) os.Error {
	// Find start element if we need it.
	if start == nil {
		for {
			tok, err := p.Token()
			if err != nil {
				return err
			}
			if t, ok := tok.(StartElement); ok {
				start = &t
				break
			}
		}
	}

	if pv, ok := val.(*reflect.PtrValue); ok {
		if pv.Get() == 0 {
			zv := reflect.MakeZero(pv.Type().(*reflect.PtrType).Elem())
			pv.PointTo(zv)
			val = zv
		} else {
			val = pv.Elem()
		}
	}

	var (
		data        []byte
		saveData    reflect.Value
		comment     []byte
		saveComment reflect.Value
		sv          *reflect.StructValue
		styp        *reflect.StructType
	)
	switch v := val.(type) {
	case *reflect.BoolValue:
		v.Set(true)

	case *reflect.SliceValue:
		typ := v.Type().(*reflect.SliceType)
		if _, ok := typ.Elem().(*reflect.Uint8Type); ok {
			// []byte
			saveData = v
			break
		}

		// Slice of element values.
		// Grow slice.
		n := v.Len()
		if n >= v.Cap() {
			ncap := 2 * n
			if ncap < 4 {
				ncap = 4
			}
			new := reflect.MakeSlice(typ, n, ncap)
			reflect.ArrayCopy(new, v)
			v.Set(new)
		}
		v.SetLen(n + 1)

		// Recur to read element into slice.
		if err := p.unmarshal(v.Elem(n), start); err != nil {
			v.SetLen(n)
			return err
		}
		return nil

	case *reflect.StringValue:
		saveData = v

	case *reflect.StructValue:
		if _, ok := v.Interface().(Name); ok {
			v.Set(reflect.NewValue(start.Name).(*reflect.StructValue))
			break
		}

		sv = v
		typ := sv.Type().(*reflect.StructType)
		styp = typ
		// Assign name.
		if f, ok := typ.FieldByName("XMLName"); ok {
			// Validate element name.
			if f.Tag != "" {
				tag := f.Tag
				ns := ""
				i := strings.LastIndex(tag, " ")
				if i >= 0 {
					ns, tag = tag[0:i], tag[i+1:]
				}
				if tag != start.Name.Local {
					return UnmarshalError("expected element type <" + tag + "> but have <" + start.Name.Local + ">")
				}
				if ns != "" && ns != start.Name.Space {
					e := "expected element <" + tag + "> in name space " + ns + " but have "
					if start.Name.Space == "" {
						e += "no name space"
					} else {
						e += start.Name.Space
					}
					return UnmarshalError(e)
				}
			}

			// Save
			v := sv.FieldByIndex(f.Index)
			if _, ok := v.Interface().(Name); !ok {
				return UnmarshalError(sv.Type().String() + " field XMLName does not have type xml.Name")
			}
			v.(*reflect.StructValue).Set(reflect.NewValue(start.Name).(*reflect.StructValue))
		}

		// Assign attributes.
		// Also, determine whether we need to save character data or comments.
		for i, n := 0, typ.NumField(); i < n; i++ {
			f := typ.Field(i)
			switch f.Tag {
			case "attr":
				strv, ok := sv.FieldByIndex(f.Index).(*reflect.StringValue)
				if !ok {
					return UnmarshalError(sv.Type().String() + " field " + f.Name + " has attr tag but is not type string")
				}
				// Look for attribute.
				val := ""
				k := strings.ToLower(f.Name)
				for _, a := range start.Attr {
					if fieldName(a.Name.Local) == k {
						val = a.Value
						break
					}
				}
				strv.Set(val)

			case "comment":
				if saveComment == nil {
					saveComment = sv.FieldByIndex(f.Index)
				}

			case "chardata":
				if saveData == nil {
					saveData = sv.FieldByIndex(f.Index)
				}
			}
		}
	}

	// Find end element.
	// Process sub-elements along the way.
Loop:
	for {
		tok, err := p.Token()
		if err != nil {
			return err
		}
		switch t := tok.(type) {
		case StartElement:
			// Sub-element.
			// Look up by tag name.
			// If that fails, fall back to mop-up field named "Any".
			if sv != nil {
				k := fieldName(t.Name.Local)
				any := -1
				for i, n := 0, styp.NumField(); i < n; i++ {
					f := styp.Field(i)
					if strings.ToLower(f.Name) == k {
						if err := p.unmarshal(sv.FieldByIndex(f.Index), &t); err != nil {
							return err
						}
						continue Loop
					}
					if any < 0 && f.Name == "Any" {
						any = i
					}
				}
				if any >= 0 {
					if err := p.unmarshal(sv.FieldByIndex(styp.Field(any).Index), &t); err != nil {
						return err
					}
					continue Loop
				}
			}
			// Not saving sub-element but still have to skip over it.
			if err := p.Skip(); err != nil {
				return err
			}

		case EndElement:
			break Loop

		case CharData:
			if saveData != nil {
				data = bytes.Add(data, t)
			}

		case Comment:
			if saveComment != nil {
				comment = bytes.Add(comment, t)
			}
		}
	}

	// Save accumulated character data and comments
	switch t := saveData.(type) {
	case *reflect.StringValue:
		t.Set(string(data))
	case *reflect.SliceValue:
		t.Set(reflect.NewValue(data).(*reflect.SliceValue))
	}

	switch t := saveComment.(type) {
	case *reflect.StringValue:
		t.Set(string(comment))
	case *reflect.SliceValue:
		t.Set(reflect.NewValue(comment).(*reflect.SliceValue))
	}

	return nil
}

// Have already read a start element.
// Read tokens until we find the end element.
// Token is taking care of making sure the
// end element matches the start element we saw.
func (p *Parser) Skip() os.Error {
	for {
		tok, err := p.Token()
		if err != nil {
			return err
		}
		switch t := tok.(type) {
		case StartElement:
			if err := p.Skip(); err != nil {
				return err
			}
		case EndElement:
			return nil
		}
	}
	panic("unreachable")
}
<commit_msg>xml: Fix comment so that example code compiles<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 xml

import (
	"bytes"
	"io"
	"os"
	"reflect"
	"strings"
	"unicode"
)

// BUG(rsc): Mapping between XML elements and data structures is inherently flawed:
// an XML element is an order-dependent collection of anonymous
// values, while a data structure is an order-independent collection
// of named values.
// See package json for a textual representation more suitable
// to data structures.

// Unmarshal parses an XML element from r and uses the
// reflect library to fill in an arbitrary struct, slice, or string
// pointed at by val.  Well-formed data that does not fit
// into val is discarded.
//
// For example, given these definitions:
//
//	type Email struct {
//		Where string "attr";
//		Addr string;
//	}
//
//	type Result struct {
//		XMLName xml.Name "result";
//		Name string;
//		Phone string;
//		Email []Email;
//	}
//
//	result := Result{ Name: "name", Phone: "phone", Email: nil }
//
// unmarshalling the XML input
//
//	<result>
//		<email where="home">
//			<addr>gre@example.com</addr>
//		</email>
//		<email where='work'>
//			<addr>gre@work.com</addr>
//		</email>
//		<name>Grace R. Emlin</name>
//		<address>123 Main Street</address>
//	</result>
//
// via Unmarshal(r, &result) is equivalent to assigning
//
//	r = Result{
//		xml.Name{"", "result"},
//		"Grace R. Emlin",	// name
//		"phone",	// no phone given
//		[]Email{
//			Email{ "home", "gre@example.com" },
//			Email{ "work", "gre@work.com" }
//		}
//	}
//
// Note that the field r.Phone has not been modified and
// that the XML <address> element was discarded.
//
// Because Unmarshal uses the reflect package, it can only
// assign to upper case fields.  Unmarshal uses a case-insensitive
// comparison to match XML element names to struct field names.
//
// Unmarshal maps an XML element to a struct using the following rules:
//
//   * If the struct has a field named XMLName of type xml.Name,
//      Unmarshal records the element name in that field.
//
//   * If the XMLName field has an associated tag string of the form
//      "tag" or "namespace-URL tag", the XML element must have
//      the given tag (and, optionally, name space) or else Unmarshal
//      returns an error.
//
//   * If the XML element has an attribute whose name matches a
//      struct field of type string with tag "attr", Unmarshal records
//      the attribute value in that field.
//
//   * If the XML element contains character data, that data is
//      accumulated in the first struct field that has tag "chardata".
//      The struct field may have type []byte or string.
//      If there is no such field, the character data is discarded.
//
//   * If the XML element contains a sub-element whose name
//      matches a struct field whose tag is neither "attr" nor "chardata",
//      Unmarshal maps the sub-element to that struct field.
//      Otherwise, if the struct has a field named Any, unmarshal
//      maps the sub-element to that struct field.
//
// Unmarshal maps an XML element to a string or []byte by saving the
// concatenation of that elements character data in the string or []byte.
//
// Unmarshal maps an XML element to a slice by extending the length
// of the slice and mapping the element to the newly created value.
//
// Unmarshal maps an XML element to a bool by setting the bool to true.
//
// Unmarshal maps an XML element to an xml.Name by recording the
// element name.
//
// Unmarshal maps an XML element to a pointer by setting the pointer
// to a freshly allocated value and then mapping the element to that value.
//
func Unmarshal(r io.Reader, val interface{}) os.Error {
	v, ok := reflect.NewValue(val).(*reflect.PtrValue)
	if !ok {
		return os.NewError("non-pointer passed to Unmarshal")
	}
	p := NewParser(r)
	elem := v.Elem()
	err := p.unmarshal(elem, nil)
	if err != nil {
		return err
	}
	return nil
}

// An UnmarshalError represents an error in the unmarshalling process.
type UnmarshalError string

func (e UnmarshalError) String() string { return string(e) }

// The Parser's Unmarshal method is like xml.Unmarshal
// except that it can be passed a pointer to the initial start element,
// useful when a client reads some raw XML tokens itself
// but also defers to Unmarshal for some elements.
// Passing a nil start element indicates that Unmarshal should
// read the token stream to find the start element.
func (p *Parser) Unmarshal(val interface{}, start *StartElement) os.Error {
	v, ok := reflect.NewValue(val).(*reflect.PtrValue)
	if !ok {
		return os.NewError("non-pointer passed to Unmarshal")
	}
	return p.unmarshal(v.Elem(), start)
}

// fieldName strips invalid characters from an XML name
// to create a valid Go struct name.  It also converts the
// name to lower case letters.
func fieldName(original string) string {
	return strings.Map(
		func(x int) int {
			if unicode.IsDigit(x) || unicode.IsLetter(x) {
				return unicode.ToLower(x)
			}
			return -1
		},
		original)
}

// Unmarshal a single XML element into val.
func (p *Parser) unmarshal(val reflect.Value, start *StartElement) os.Error {
	// Find start element if we need it.
	if start == nil {
		for {
			tok, err := p.Token()
			if err != nil {
				return err
			}
			if t, ok := tok.(StartElement); ok {
				start = &t
				break
			}
		}
	}

	if pv, ok := val.(*reflect.PtrValue); ok {
		if pv.Get() == 0 {
			zv := reflect.MakeZero(pv.Type().(*reflect.PtrType).Elem())
			pv.PointTo(zv)
			val = zv
		} else {
			val = pv.Elem()
		}
	}

	var (
		data        []byte
		saveData    reflect.Value
		comment     []byte
		saveComment reflect.Value
		sv          *reflect.StructValue
		styp        *reflect.StructType
	)
	switch v := val.(type) {
	case *reflect.BoolValue:
		v.Set(true)

	case *reflect.SliceValue:
		typ := v.Type().(*reflect.SliceType)
		if _, ok := typ.Elem().(*reflect.Uint8Type); ok {
			// []byte
			saveData = v
			break
		}

		// Slice of element values.
		// Grow slice.
		n := v.Len()
		if n >= v.Cap() {
			ncap := 2 * n
			if ncap < 4 {
				ncap = 4
			}
			new := reflect.MakeSlice(typ, n, ncap)
			reflect.ArrayCopy(new, v)
			v.Set(new)
		}
		v.SetLen(n + 1)

		// Recur to read element into slice.
		if err := p.unmarshal(v.Elem(n), start); err != nil {
			v.SetLen(n)
			return err
		}
		return nil

	case *reflect.StringValue:
		saveData = v

	case *reflect.StructValue:
		if _, ok := v.Interface().(Name); ok {
			v.Set(reflect.NewValue(start.Name).(*reflect.StructValue))
			break
		}

		sv = v
		typ := sv.Type().(*reflect.StructType)
		styp = typ
		// Assign name.
		if f, ok := typ.FieldByName("XMLName"); ok {
			// Validate element name.
			if f.Tag != "" {
				tag := f.Tag
				ns := ""
				i := strings.LastIndex(tag, " ")
				if i >= 0 {
					ns, tag = tag[0:i], tag[i+1:]
				}
				if tag != start.Name.Local {
					return UnmarshalError("expected element type <" + tag + "> but have <" + start.Name.Local + ">")
				}
				if ns != "" && ns != start.Name.Space {
					e := "expected element <" + tag + "> in name space " + ns + " but have "
					if start.Name.Space == "" {
						e += "no name space"
					} else {
						e += start.Name.Space
					}
					return UnmarshalError(e)
				}
			}

			// Save
			v := sv.FieldByIndex(f.Index)
			if _, ok := v.Interface().(Name); !ok {
				return UnmarshalError(sv.Type().String() + " field XMLName does not have type xml.Name")
			}
			v.(*reflect.StructValue).Set(reflect.NewValue(start.Name).(*reflect.StructValue))
		}

		// Assign attributes.
		// Also, determine whether we need to save character data or comments.
		for i, n := 0, typ.NumField(); i < n; i++ {
			f := typ.Field(i)
			switch f.Tag {
			case "attr":
				strv, ok := sv.FieldByIndex(f.Index).(*reflect.StringValue)
				if !ok {
					return UnmarshalError(sv.Type().String() + " field " + f.Name + " has attr tag but is not type string")
				}
				// Look for attribute.
				val := ""
				k := strings.ToLower(f.Name)
				for _, a := range start.Attr {
					if fieldName(a.Name.Local) == k {
						val = a.Value
						break
					}
				}
				strv.Set(val)

			case "comment":
				if saveComment == nil {
					saveComment = sv.FieldByIndex(f.Index)
				}

			case "chardata":
				if saveData == nil {
					saveData = sv.FieldByIndex(f.Index)
				}
			}
		}
	}

	// Find end element.
	// Process sub-elements along the way.
Loop:
	for {
		tok, err := p.Token()
		if err != nil {
			return err
		}
		switch t := tok.(type) {
		case StartElement:
			// Sub-element.
			// Look up by tag name.
			// If that fails, fall back to mop-up field named "Any".
			if sv != nil {
				k := fieldName(t.Name.Local)
				any := -1
				for i, n := 0, styp.NumField(); i < n; i++ {
					f := styp.Field(i)
					if strings.ToLower(f.Name) == k {
						if err := p.unmarshal(sv.FieldByIndex(f.Index), &t); err != nil {
							return err
						}
						continue Loop
					}
					if any < 0 && f.Name == "Any" {
						any = i
					}
				}
				if any >= 0 {
					if err := p.unmarshal(sv.FieldByIndex(styp.Field(any).Index), &t); err != nil {
						return err
					}
					continue Loop
				}
			}
			// Not saving sub-element but still have to skip over it.
			if err := p.Skip(); err != nil {
				return err
			}

		case EndElement:
			break Loop

		case CharData:
			if saveData != nil {
				data = bytes.Add(data, t)
			}

		case Comment:
			if saveComment != nil {
				comment = bytes.Add(comment, t)
			}
		}
	}

	// Save accumulated character data and comments
	switch t := saveData.(type) {
	case *reflect.StringValue:
		t.Set(string(data))
	case *reflect.SliceValue:
		t.Set(reflect.NewValue(data).(*reflect.SliceValue))
	}

	switch t := saveComment.(type) {
	case *reflect.StringValue:
		t.Set(string(comment))
	case *reflect.SliceValue:
		t.Set(reflect.NewValue(comment).(*reflect.SliceValue))
	}

	return nil
}

// Have already read a start element.
// Read tokens until we find the end element.
// Token is taking care of making sure the
// end element matches the start element we saw.
func (p *Parser) Skip() os.Error {
	for {
		tok, err := p.Token()
		if err != nil {
			return err
		}
		switch t := tok.(type) {
		case StartElement:
			if err := p.Skip(); err != nil {
				return err
			}
		case EndElement:
			return nil
		}
	}
	panic("unreachable")
}
<|endoftext|>


<commit_before>package boil

import (
	"database/sql"
	"os"
)

type Executor interface {
	Exec(query string, args ...interface{}) (sql.Result, error)
	Query(query string, args ...interface{}) (*sql.Rows, error)
	QueryRow(query string, args ...interface{}) *sql.Row
}

type Transactor interface {
	Commit() error
	Rollback() error

	Executor
}

type Creator interface {
	Begin() (*sql.Tx, error)
}

var currentDB Executor

// DebugMode is a flag controlling whether generated sql statements and
// debug information is outputted to the DebugWriter handle
//
// NOTE: This should be disabled in production to avoid leaking sensitive data
var DebugMode = false

// DebugWriter is where the debug output will be sent if DebugMode is true
var DebugWriter = os.Stdout

func Begin() (Transactor, error) {
	creator, ok := currentDB.(Creator)
	if !ok {
		panic("Your database does not support transactions.")
	}

	return creator.Begin()
}

// SetDB initializes the database handle for all template db interactions
func SetDB(db Executor) {
	currentDB = db
}

// GetDB retrieves the global state database handle
func GetDB() Executor {
	return currentDB
}
<commit_msg>Fix some documentation and ugly constant placement<commit_after>package boil

import (
	"database/sql"
	"os"
)

var (
	// currentDB is a global database handle for the package
	currentDB Executor
)

// Executor can perform SQL queries.
type Executor interface {
	Exec(query string, args ...interface{}) (sql.Result, error)
	Query(query string, args ...interface{}) (*sql.Rows, error)
	QueryRow(query string, args ...interface{}) *sql.Row
}

// Transactor can commit and rollback, on top of being able to execute queries.
type Transactor interface {
	Commit() error
	Rollback() error

	Executor
}

// Creator starts transactions.
type Creator interface {
	Begin() (*sql.Tx, error)
}

// DebugMode is a flag controlling whether generated sql statements and
// debug information is outputted to the DebugWriter handle
//
// NOTE: This should be disabled in production to avoid leaking sensitive data
var DebugMode = false

// DebugWriter is where the debug output will be sent if DebugMode is true
var DebugWriter = os.Stdout

// Begin a transaction
func Begin() (Transactor, error) {
	creator, ok := currentDB.(Creator)
	if !ok {
		panic("Your database does not support transactions.")
	}

	return creator.Begin()
}

// SetDB initializes the database handle for all template db interactions
func SetDB(db Executor) {
	currentDB = db
}

// GetDB retrieves the global state database handle
func GetDB() Executor {
	return currentDB
}
<|endoftext|>