libgo: Update to weekly.2012-03-22.
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 30 Mar 2012 22:09:55 +0000 (22:09 +0000)
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 30 Mar 2012 22:09:55 +0000 (22:09 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@186026 138bc75d-0d04-0410-961f-82ee72b054a4

51 files changed:
libgo/MERGE
libgo/go/archive/zip/reader_test.go
libgo/go/crypto/tls/handshake_client.go
libgo/go/encoding/gob/doc.go
libgo/go/encoding/json/encode.go
libgo/go/exp/norm/normalize.go
libgo/go/exp/types/universe.go
libgo/go/flag/example_test.go [new file with mode: 0644]
libgo/go/fmt/scan_test.go
libgo/go/go/build/build.go
libgo/go/go/build/build_test.go
libgo/go/go/printer/nodes.go
libgo/go/go/printer/testdata/declarations.golden
libgo/go/go/printer/testdata/declarations.input
libgo/go/html/template/clone_test.go
libgo/go/html/template/content.go
libgo/go/html/template/escape.go
libgo/go/html/template/escape_test.go
libgo/go/html/template/template.go
libgo/go/image/draw/draw.go
libgo/go/index/suffixarray/qsufsort.go
libgo/go/io/ioutil/ioutil.go
libgo/go/log/syslog/syslog_windows.go [new file with mode: 0644]
libgo/go/math/big/nat.go
libgo/go/math/erf.go
libgo/go/net/http/triv.go
libgo/go/net/interface_linux.go
libgo/go/net/interface_stub.go
libgo/go/net/interface_windows.go
libgo/go/net/unicast_test.go
libgo/go/os/error.go
libgo/go/os/error_plan9.go
libgo/go/os/error_posix.go
libgo/go/os/error_test.go
libgo/go/os/error_windows.go
libgo/go/os/file_unix.go
libgo/go/os/os_test.go
libgo/go/path/filepath/match.go
libgo/go/path/filepath/match_test.go
libgo/go/reflect/type.go
libgo/go/reflect/value.go
libgo/go/sort/sort.go
libgo/go/text/template/exec.go
libgo/go/text/template/exec_test.go
libgo/go/text/template/multi_test.go
libgo/go/text/template/parse/lex.go
libgo/go/text/template/parse/parse.go
libgo/go/text/template/parse/parse_test.go
libgo/merge.sh
libgo/runtime/proc.c
libgo/runtime/runtime.c

index 13b0438..e7e992c 100644 (file)
@@ -1,4 +1,4 @@
-3cdba7b0650c
+bce220d03774
 
 The first line of this file holds the Mercurial revision number of the
 last merge done from the master library sources.
index c2db0dc..5f1d1b2 100644 (file)
@@ -7,10 +7,12 @@ package zip
 import (
        "bytes"
        "encoding/binary"
+       "encoding/hex"
        "io"
        "io/ioutil"
        "os"
        "path/filepath"
+       "regexp"
        "testing"
        "time"
 )
@@ -62,13 +64,14 @@ var tests = []ZipTest{
                },
        },
        {
-               Name: "r.zip",
+               Name:   "r.zip",
+               Source: returnRecursiveZip,
                File: []ZipTestFile{
                        {
-                               Name:  "r/r.zip",
-                               File:  "r.zip",
-                               Mtime: "03-04-10 00:24:16",
-                               Mode:  0666,
+                               Name:    "r/r.zip",
+                               Content: rZipBytes(),
+                               Mtime:   "03-04-10 00:24:16",
+                               Mode:    0666,
                        },
                },
        },
@@ -415,3 +418,49 @@ func returnCorruptNotStreamedZip() (r io.ReaderAt, size int64) {
                // is what matters.
        })
 }
+
+// rZipBytes returns the bytes of a recursive zip file, without
+// putting it on disk and triggering certain virus scanners.
+func rZipBytes() []byte {
+       s := `
+0000000 50 4b 03 04 14 00 00 00 08 00 08 03 64 3c f9 f4
+0000010 89 64 48 01 00 00 b8 01 00 00 07 00 00 00 72 2f
+0000020 72 2e 7a 69 70 00 25 00 da ff 50 4b 03 04 14 00
+0000030 00 00 08 00 08 03 64 3c f9 f4 89 64 48 01 00 00
+0000040 b8 01 00 00 07 00 00 00 72 2f 72 2e 7a 69 70 00
+0000050 2f 00 d0 ff 00 25 00 da ff 50 4b 03 04 14 00 00
+0000060 00 08 00 08 03 64 3c f9 f4 89 64 48 01 00 00 b8
+0000070 01 00 00 07 00 00 00 72 2f 72 2e 7a 69 70 00 2f
+0000080 00 d0 ff c2 54 8e 57 39 00 05 00 fa ff c2 54 8e
+0000090 57 39 00 05 00 fa ff 00 05 00 fa ff 00 14 00 eb
+00000a0 ff c2 54 8e 57 39 00 05 00 fa ff 00 05 00 fa ff
+00000b0 00 14 00 eb ff 42 88 21 c4 00 00 14 00 eb ff 42
+00000c0 88 21 c4 00 00 14 00 eb ff 42 88 21 c4 00 00 14
+00000d0 00 eb ff 42 88 21 c4 00 00 14 00 eb ff 42 88 21
+00000e0 c4 00 00 00 00 ff ff 00 00 00 ff ff 00 34 00 cb
+00000f0 ff 42 88 21 c4 00 00 00 00 ff ff 00 00 00 ff ff
+0000100 00 34 00 cb ff 42 e8 21 5e 0f 00 00 00 ff ff 0a
+0000110 f0 66 64 12 61 c0 15 dc e8 a0 48 bf 48 af 2a b3
+0000120 20 c0 9b 95 0d c4 67 04 42 53 06 06 06 40 00 06
+0000130 00 f9 ff 6d 01 00 00 00 00 42 e8 21 5e 0f 00 00
+0000140 00 ff ff 0a f0 66 64 12 61 c0 15 dc e8 a0 48 bf
+0000150 48 af 2a b3 20 c0 9b 95 0d c4 67 04 42 53 06 06
+0000160 06 40 00 06 00 f9 ff 6d 01 00 00 00 00 50 4b 01
+0000170 02 14 00 14 00 00 00 08 00 08 03 64 3c f9 f4 89
+0000180 64 48 01 00 00 b8 01 00 00 07 00 00 00 00 00 00
+0000190 00 00 00 00 00 00 00 00 00 00 00 72 2f 72 2e 7a
+00001a0 69 70 50 4b 05 06 00 00 00 00 01 00 01 00 35 00
+00001b0 00 00 6d 01 00 00 00 00`
+       s = regexp.MustCompile(`[0-9a-f]{7}`).ReplaceAllString(s, "")
+       s = regexp.MustCompile(`\s+`).ReplaceAllString(s, "")
+       b, err := hex.DecodeString(s)
+       if err != nil {
+               panic(err)
+       }
+       return b
+}
+
+func returnRecursiveZip() (r io.ReaderAt, size int64) {
+       b := rZipBytes()
+       return bytes.NewReader(b), int64(len(b))
+}
index 266eb8f..2877f17 100644 (file)
@@ -166,8 +166,11 @@ func (c *Conn) clientHandshake() error {
        }
 
        var certToSend *Certificate
+       var certRequested bool
        certReq, ok := msg.(*certificateRequestMsg)
        if ok {
+               certRequested = true
+
                // RFC 4346 on the certificateAuthorities field:
                // A list of the distinguished names of acceptable certificate
                // authorities. These distinguished names may specify a desired
@@ -238,9 +241,14 @@ func (c *Conn) clientHandshake() error {
        }
        finishedHash.Write(shd.marshal())
 
-       if certToSend != nil {
+       // If the server requested a certificate then we have to send a
+       // Certificate message, even if it's empty because we don't have a
+       // certificate to send.
+       if certRequested {
                certMsg = new(certificateMsg)
-               certMsg.certificates = certToSend.Certificate
+               if certToSend != nil {
+                       certMsg.certificates = certToSend.Certificate
+               }
                finishedHash.Write(certMsg.marshal())
                c.writeRecord(recordTypeHandshake, certMsg.marshal())
        }
index c9ad18e..96885f8 100644 (file)
@@ -226,7 +226,7 @@ where * signifies zero or more repetitions and the type id of a value must
 be predefined or be defined before the value in the stream.
 
 See "Gobs of data" for a design discussion of the gob wire format:
-http://blog.golang.org/2011/03/gobs-of-data.html
+http://golang.org/doc/articles/gobs_of_data.html
 */
 package gob
 
index edbafcf..14957b8 100644 (file)
@@ -6,7 +6,7 @@
 // RFC 4627.
 //
 // See "JSON and Go" for an introduction to this package:
-// http://blog.golang.org/2011/01/json-and-go.html
+// http://golang.org/doc/articles/json_and_go.html
 package json
 
 import (
index b5cd44a..c1d74f8 100644 (file)
@@ -356,7 +356,7 @@ func lastBoundary(fd *formInfo, b []byte) int {
                return -1
        }
        if info.size == 0 { // ends with incomplete rune
-               if p == 0 { // starts wtih incomplete rune
+               if p == 0 { // starts with incomplete rune
                        return -1
                }
                i = p
index 46cff31..cb89397 100644 (file)
@@ -102,11 +102,6 @@ func init() {
        defType("Pointer")
 
        defFun("Alignof")
-       defFun("New")
-       defFun("NewArray")
        defFun("Offsetof")
-       defFun("Reflect")
        defFun("Sizeof")
-       defFun("Typeof")
-       defFun("Unreflect")
 }
diff --git a/libgo/go/flag/example_test.go b/libgo/go/flag/example_test.go
new file mode 100644 (file)
index 0000000..04a0d20
--- /dev/null
@@ -0,0 +1,83 @@
+// 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.
+
+// These examples demonstrate more intricate uses of the flag package.
+package flag_test
+
+import (
+       "errors"
+       "flag"
+       "fmt"
+       "strings"
+       "time"
+)
+
+// Example 1: A single string flag called "species" with default value "gopher".
+var species = flag.String("species", "gopher", "the species we are studying")
+
+// Example 2: Two flags sharing a variable, so we can have a shorthand.
+// The order of initialization is undefined, so make sure both use the
+// same default value. They must be set up with an init function.
+var gopherType string
+
+func init() {
+       const (
+               defaultGopher = "pocket"
+               usage         = "the variety of gopher"
+       )
+       flag.StringVar(&gopherType, "gopher_type", defaultGopher, usage)
+       flag.StringVar(&gopherType, "g", defaultGopher, usage+" (shorthand)")
+}
+
+// Example 3: A user-defined flag type, a slice of durations.
+type interval []time.Duration
+
+// String is the method to format the flag's value, part of the flag.Value interface.
+// The String method's output will be used in diagnostics.
+func (i *interval) String() string {
+       return fmt.Sprint(*i)
+}
+
+// Set is the method to set the flag value, part of the flag.Value interface.
+// Set's argument is a string to be parsed to set the flag.
+// It's a comma-separated list, so we split it.
+func (i *interval) Set(value string) error {
+       // If we wanted to allow the flag to be set multiple times,
+       // accumulating values, we would delete this if statement.
+       // That would permit usages such as
+       //      -deltaT 10s -deltaT 15s
+       // and other combinations.
+       if len(*i) > 0 {
+               return errors.New("interval flag already set")
+       }
+       for _, dt := range strings.Split(value, ",") {
+               duration, err := time.ParseDuration(dt)
+               if err != nil {
+                       return err
+               }
+               *i = append(*i, duration)
+       }
+       return nil
+}
+
+// Define a flag to accumulate durations. Because it has a special type,
+// we need to use the Var function and therefore create the flag during
+// init.
+
+var intervalFlag interval
+
+func init() {
+       // Tie the command-line flag to the intervalFlag variable and
+       // set a usage message.
+       flag.Var(&intervalFlag, "deltaT", "comma-separated list of intervals to use between events")
+}
+
+func Example() {
+       // All the interesting pieces are with the variables declared above, but
+       // to enable the flag package to see the flags defined there, one must
+       // execute, typically at the start of main (not init!):
+       //      flag.Parse()
+       // We don't run it here because this is not a main function and
+       // the testing suite has already parsed the flags.
+}
index 61b48f9..320857b 100644 (file)
@@ -810,7 +810,7 @@ func TestMultiLine(t *testing.T) {
        }
 }
 
-// RecursiveInt accepts an string matching %d.%d.%d....
+// RecursiveInt accepts a string matching %d.%d.%d....
 // and parses it into a linked list.
 // It allows us to benchmark recursive descent style scanners.
 type RecursiveInt struct {
@@ -826,7 +826,7 @@ func (r *RecursiveInt) Scan(state ScanState, verb rune) (err error) {
        next := new(RecursiveInt)
        _, err = Fscanf(state, ".%v", next)
        if err != nil {
-               if err == errors.New("input does not match format") || err == io.ErrUnexpectedEOF {
+               if err == io.ErrUnexpectedEOF {
                        err = nil
                }
                return
index dc9dcd1..d113dc1 100644 (file)
@@ -328,22 +328,22 @@ func (e *NoGoError) Error() string {
 }
 
 // Import returns details about the Go package named by the import path,
-// interpreting local import paths relative to the src directory.  If the path
-// is a local import path naming a package that can be imported using a
-// standard import path, the returned package will set p.ImportPath to
-// that path.
+// interpreting local import paths relative to the srcDir directory.
+// If the path is a local import path naming a package that can be imported
+// using a standard import path, the returned package will set p.ImportPath
+// to that path.
 //
 // In the directory containing the package, .go, .c, .h, and .s files are
 // considered part of the package except for:
 //
 //     - .go files in package documentation
-//     - files starting with _ or .
+//     - files starting with _ or . (likely editor temporary files)
 //     - files with build constraints not satisfied by the context
 //
 // If an error occurs, Import returns a non-nil error also returns a non-nil
 // *Package containing partial information.
 //
-func (ctxt *Context) Import(path string, src string, mode ImportMode) (*Package, error) {
+func (ctxt *Context) Import(path string, srcDir string, mode ImportMode) (*Package, error) {
        p := &Package{
                ImportPath: path,
        }
@@ -363,11 +363,12 @@ func (ctxt *Context) Import(path string, src string, mode ImportMode) (*Package,
 
        binaryOnly := false
        if IsLocalImport(path) {
-               if src == "" {
+               pkga = "" // local imports have no installed path
+               if srcDir == "" {
                        return p, fmt.Errorf("import %q: import relative to unknown directory", path)
                }
                if !ctxt.isAbsPath(path) {
-                       p.Dir = ctxt.joinPath(src, path)
+                       p.Dir = ctxt.joinPath(srcDir, path)
                }
                // Determine canonical import path, if any.
                if ctxt.GOROOT != "" {
@@ -640,8 +641,8 @@ func cleanImports(m map[string][]token.Position) ([]string, map[string][]token.P
 }
 
 // Import is shorthand for Default.Import.
-func Import(path, src string, mode ImportMode) (*Package, error) {
-       return Default.Import(path, src, mode)
+func Import(path, srcDir string, mode ImportMode) (*Package, error) {
+       return Default.Import(path, srcDir, mode)
 }
 
 // ImportDir is shorthand for Default.ImportDir.
@@ -874,7 +875,7 @@ func splitQuoted(s string) (r []string, err error) {
 //     !cgo (if cgo is disabled)
 //     tag (if tag is listed in ctxt.BuildTags)
 //     !tag (if tag is not listed in ctxt.BuildTags)
-//     a slash-separated list of any of these
+//     a comma-separated list of any of these
 //
 func (ctxt *Context) match(name string) bool {
        if name == "" {
@@ -888,11 +889,11 @@ func (ctxt *Context) match(name string) bool {
                return false
        }
        if strings.HasPrefix(name, "!") { // negation
-               return !ctxt.match(name[1:])
+               return len(name) > 1 && !ctxt.match(name[1:])
        }
 
        // Tags must be letters, digits, underscores.
-       // Unlike in Go identifiers, all digits is fine (e.g., "386").
+       // Unlike in Go identifiers, all digits are fine (e.g., "386").
        for _, c := range name {
                if !unicode.IsLetter(c) && !unicode.IsDigit(c) && c != '_' {
                        return false
index 06b8b0e..560ebad 100644 (file)
@@ -36,6 +36,7 @@ func TestMatch(t *testing.T) {
        nomatch(runtime.GOOS + "," + runtime.GOARCH + ",!foo")
        match(runtime.GOOS + "," + runtime.GOARCH + ",!bar")
        nomatch(runtime.GOOS + "," + runtime.GOARCH + ",bar")
+       nomatch("!")
 }
 
 func TestDotSlashImport(t *testing.T) {
index 6be3c09..727d2a3 100644 (file)
@@ -365,7 +365,7 @@ func (p *printer) setLineComment(text string) {
 }
 
 func (p *printer) isMultiLine(n ast.Node) bool {
-       return p.lineFor(n.End())-p.lineFor(n.Pos()) > 1
+       return p.lineFor(n.End())-p.lineFor(n.Pos()) > 0
 }
 
 func (p *printer) fieldList(fields *ast.FieldList, isStruct, isIncomplete bool) {
index 7ed7cb6..71ed32e 100644 (file)
@@ -500,7 +500,7 @@ type _ struct {
 
 type _ struct {
        a, b,
-       c, d            int     // this line should be indented
+       c, d    int     // this line should be indented
        u, v, w, x      float   // this line should be indented
        p, q,
        r, s    float   // this line should be indented
@@ -562,10 +562,21 @@ var a2, b2,
 
 var (
        a3, b3,
-       c3, d3          int     // this line should be indented
+       c3, d3  int     // this line should be indented
        a4, b4, c4      int     // this line should be indented
 )
 
+// Test case from issue 3304: multi-line declarations must end
+// a formatting section and not influence indentation of the
+// next line.
+var (
+       minRefreshTimeSec       = flag.Int64("min_refresh_time_sec", 604800,
+               "minimum time window between two refreshes for a given user.")
+       x       = flag.Int64("refresh_user_rollout_percent", 100,
+               "temporary flag to ramp up the refresh user rpc")
+       aVeryLongVariableName   = stats.GetVarInt("refresh-user-count")
+)
+
 func _() {
        var privateKey2 = &Block{Type:  "RSA PRIVATE KEY",
                Headers:        map[string]string{},
index df8c2b1..d74cff2 100644 (file)
@@ -577,6 +577,16 @@ c3, d3 int  // this line should be indented
 a4, b4, c4 int  // this line should be indented
 )
 
+// Test case from issue 3304: multi-line declarations must end
+// a formatting section and not influence indentation of the
+// next line.
+var (
+       minRefreshTimeSec = flag.Int64("min_refresh_time_sec", 604800,
+               "minimum time window between two refreshes for a given user.")
+       x = flag.Int64("refresh_user_rollout_percent", 100,
+               "temporary flag to ramp up the refresh user rpc")
+       aVeryLongVariableName = stats.GetVarInt("refresh-user-count")
+)
 
 func _() {
        var privateKey2 = &Block{Type: "RSA PRIVATE KEY",
index c612775..2663cdd 100644 (file)
@@ -113,3 +113,36 @@ func TestClone(t *testing.T) {
                t.Errorf("t3: got %q want %q", got, want)
        }
 }
+
+func TestTemplates(t *testing.T) {
+       names := []string{"t0", "a", "lhs", "rhs"}
+       // Some template definitions borrowed from TestClone.
+       const tmpl = `
+               {{define "a"}}{{template "lhs"}}{{.}}{{template "rhs"}}{{end}}
+               {{define "lhs"}} <a href=" {{end}}
+               {{define "rhs"}} "></a> {{end}}`
+       t0 := Must(New("t0").Parse(tmpl))
+       templates := t0.Templates()
+       if len(templates) != len(names) {
+               t.Errorf("expected %d templates; got %d", len(names), len(templates))
+       }
+       for _, name := range names {
+               found := false
+               for _, tmpl := range templates {
+                       if name == tmpl.text.Name() {
+                               found = true
+                               break
+                       }
+               }
+               if !found {
+                       t.Error("could not find template", name)
+               }
+       }
+}
+
+// This used to crash; http://golang.org/issue/3281
+func TestCloneCrash(t *testing.T) {
+       t1 := New("all")
+       Must(t1.New("t1").Parse(`{{define "foo"}}foo{{end}}`))
+       t1.Clone()
+}
index 539664f..c1bd2e4 100644 (file)
@@ -26,10 +26,10 @@ type (
        HTML string
 
        // HTMLAttr encapsulates an HTML attribute from a trusted source,
-       // for example: ` dir="ltr"`.
+       // for example, ` dir="ltr"`.
        HTMLAttr string
 
-       // JS encapsulates a known safe EcmaScript5 Expression, or example,
+       // JS encapsulates a known safe EcmaScript5 Expression, for example,
        // `(x + y * z())`. 
        // Template authors are responsible for ensuring that typed expressions
        // do not break the intended precedence and that there is no
index a058e20..5f0e28e 100644 (file)
@@ -8,6 +8,7 @@ import (
        "bytes"
        "fmt"
        "html"
+       "io"
        "text/template"
        "text/template/parse"
 )
@@ -751,3 +752,44 @@ func (e *escaper) template(name string) *template.Template {
        }
        return t
 }
+
+// Forwarding functions so that clients need only import this package
+// to reach the general escaping functions of text/template.
+
+// HTMLEscape writes to w the escaped HTML equivalent of the plain text data b.
+func HTMLEscape(w io.Writer, b []byte) {
+       template.HTMLEscape(w, b)
+}
+
+// HTMLEscapeString returns the escaped HTML equivalent of the plain text data s.
+func HTMLEscapeString(s string) string {
+       return template.HTMLEscapeString(s)
+}
+
+// HTMLEscaper returns the escaped HTML equivalent of the textual
+// representation of its arguments.
+func HTMLEscaper(args ...interface{}) string {
+       return template.HTMLEscaper(args...)
+}
+
+// JSEscape writes to w the escaped JavaScript equivalent of the plain text data b.
+func JSEscape(w io.Writer, b []byte) {
+       template.JSEscape(w, b)
+}
+
+// JSEscapeString returns the escaped JavaScript equivalent of the plain text data s.
+func JSEscapeString(s string) string {
+       return template.JSEscapeString(s)
+}
+
+// JSEscaper returns the escaped JavaScript equivalent of the textual
+// representation of its arguments.
+func JSEscaper(args ...interface{}) string {
+       return template.JSEscaper(args...)
+}
+
+// URLQueryEscaper returns the escaped value of the textual representation of
+// its arguments in a form suitable for embedding in a URL query.
+func URLQueryEscaper(args ...interface{}) string {
+       return template.URLQueryEscaper(args...)
+}
index 2bbb1b1..ce12c17 100644 (file)
@@ -8,6 +8,7 @@ import (
        "bytes"
        "encoding/json"
        "fmt"
+       "os"
        "strings"
        "testing"
        "text/template"
@@ -1637,6 +1638,14 @@ func TestIndirectPrint(t *testing.T) {
        }
 }
 
+// This is a test for issue 3272.
+func TestEmptyTemplate(t *testing.T) {
+       page := Must(New("page").ParseFiles(os.DevNull))
+       if err := page.ExecuteTemplate(os.Stdout, "page", "nothing"); err == nil {
+               t.Fatal("expected error")
+       }
+}
+
 func BenchmarkEscapedExecute(b *testing.B) {
        tmpl := Must(New("t").Parse(`<a onclick="alert('{{.}}')">{{.}}</a>`))
        var buf bytes.Buffer
index b0bae7a..edac733 100644 (file)
@@ -31,6 +31,20 @@ type nameSpace struct {
        set map[string]*Template
 }
 
+// Templates returns a slice of the templates associated with t, including t
+// itself.
+func (t *Template) Templates() []*Template {
+       ns := t.nameSpace
+       ns.mu.Lock()
+       defer ns.mu.Unlock()
+       // Return a slice so we don't expose the map.
+       m := make([]*Template, 0, len(ns.set))
+       for _, v := range ns.set {
+               m = append(m, v)
+       }
+       return m
+}
+
 // Execute applies a parsed template to the specified data object,
 // writing the output to wr.
 func (t *Template) Execute(wr io.Writer, data interface{}) (err error) {
@@ -64,7 +78,13 @@ func (t *Template) lookupAndEscapeTemplate(name string) (tmpl *Template, err err
        t.nameSpace.mu.Lock()
        defer t.nameSpace.mu.Unlock()
        tmpl = t.set[name]
-       if (tmpl == nil) != (t.text.Lookup(name) == nil) {
+       if tmpl == nil {
+               return nil, fmt.Errorf("html/template: %q is undefined", name)
+       }
+       if tmpl.text.Tree == nil || tmpl.text.Root == nil {
+               return nil, fmt.Errorf("html/template: %q is an incomplete template", name)
+       }
+       if t.text.Lookup(name) == nil {
                panic("html/template internal error: template escaping out of sync")
        }
        if tmpl != nil && !tmpl.escaped {
@@ -160,9 +180,11 @@ func (t *Template) Clone() (*Template, error) {
                if src == nil || src.escaped {
                        return nil, fmt.Errorf("html/template: cannot Clone %q after it has executed", t.Name())
                }
-               x.Tree = &parse.Tree{
-                       Name: x.Tree.Name,
-                       Root: x.Tree.Root.CopyList(),
+               if x.Tree != nil {
+                       x.Tree = &parse.Tree{
+                               Name: x.Tree.Name,
+                               Root: x.Tree.Root.CopyList(),
+                       }
                }
                ret.set[name] = &Template{
                        false,
@@ -274,7 +296,7 @@ func (t *Template) ParseFiles(filenames ...string) (*Template, error) {
 func parseFiles(t *Template, filenames ...string) (*Template, error) {
        if len(filenames) == 0 {
                // Not really a problem, but be consistent.
-               return nil, fmt.Errorf("template: no files named in call to ParseFiles")
+               return nil, fmt.Errorf("html/template: no files named in call to ParseFiles")
        }
        for _, filename := range filenames {
                b, err := ioutil.ReadFile(filename)
@@ -331,7 +353,7 @@ func parseGlob(t *Template, pattern string) (*Template, error) {
                return nil, err
        }
        if len(filenames) == 0 {
-               return nil, fmt.Errorf("template: pattern matches no files: %#q", pattern)
+               return nil, fmt.Errorf("html/template: pattern matches no files: %#q", pattern)
        }
        return parseFiles(t, filenames...)
 }
index 3b6679f..bef325c 100644 (file)
@@ -5,7 +5,7 @@
 // Package draw provides image composition functions.
 //
 // See "The Go image/draw package" for an introduction to this package:
-// http://blog.golang.org/2011/09/go-imagedraw-package.html
+// http://golang.org/doc/articles/image_draw.html
 package draw
 
 import (
index c69be43..9c36a98 100644 (file)
@@ -11,7 +11,7 @@
 // Consecutive groups of suffixes in sa are labeled as sorted groups or
 // unsorted groups. For a given pass of the sorter, all suffixes are ordered
 // up to their first h characters, and sa is h-ordered. Suffixes in their
-// final positions and unambiguouly sorted in h-order are in a sorted group.
+// final positions and unambiguously sorted in h-order are in a sorted group.
 // Consecutive groups of suffixes with identical first h characters are an
 // unsorted group. In each pass of the algorithm, unsorted groups are sorted
 // according to the group number of their following suffix.
@@ -78,7 +78,7 @@ func sortedByFirstByte(data []byte) []int {
        for _, b := range data {
                count[b]++
        }
-       // make count[b] equal index of first occurence of b in sorted array
+       // make count[b] equal index of first occurrence of b in sorted array
        sum := 0
        for b := range count {
                count[b], sum = sum, count[b]+sum
index 180afc2..f072b8c 100644 (file)
@@ -53,10 +53,13 @@ func ReadFile(filename string) ([]byte, error) {
        defer f.Close()
        // It's a good but not certain bet that FileInfo will tell us exactly how much to
        // read, so let's try it but be prepared for the answer to be wrong.
-       fi, err := f.Stat()
        var n int64
-       if size := fi.Size(); err == nil && size < 2e9 { // Don't preallocate a huge buffer, just in case.
-               n = size
+
+       if fi, err := f.Stat(); err == nil {
+               // Don't preallocate a huge buffer, just in case.
+               if size := fi.Size(); size < 1e9 {
+                       n = size
+               }
        }
        // As initial capacity for readAll, use n + a little extra in case Size is zero,
        // and to avoid another allocation after Read has filled the buffer.  The readAll
diff --git a/libgo/go/log/syslog/syslog_windows.go b/libgo/go/log/syslog/syslog_windows.go
new file mode 100644 (file)
index 0000000..8d99e2e
--- /dev/null
@@ -0,0 +1,8 @@
+// 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.
+
+// Package syslog provides a simple interface to the system log service.
+package syslog
+
+// BUG(brainman): This package is not implemented on Windows yet.
index da1ac94..0bc6572 100644 (file)
@@ -826,7 +826,7 @@ func (x nat) string(charset string) string {
 // iterative approach. This threshold is represented by leafSize. Benchmarking of leafSize in the 
 // range 2..64 shows that values of 8 and 16 work well, with a 4x speedup at medium lengths and 
 // ~30x for 20000 digits. Use nat_test.go's BenchmarkLeafSize tests to optimize leafSize for 
-// specfic hardware.
+// specific hardware.
 //
 func (q nat) convertWords(s []byte, charset string, b Word, ndigits int, bb Word, table []divisor) {
        // split larger blocks recursively
index 87c70c2..c6f32bd 100644 (file)
@@ -248,7 +248,7 @@ func Erf(x float64) float64 {
                R = rb0 + s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(rb5+s*rb6)))))
                S = 1 + s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(sb5+s*(sb6+s*sb7))))))
        }
-       z := Float64frombits(Float64bits(x) & 0xffffffff00000000) // pseudo-single (20-bit) precison x
+       z := Float64frombits(Float64bits(x) & 0xffffffff00000000) // pseudo-single (20-bit) precision x
        r := Exp(-z*z-0.5625) * Exp((z-x)*(z+x)+R/S)
        if sign {
                return r/x - 1
@@ -321,7 +321,7 @@ func Erfc(x float64) float64 {
                        R = rb0 + s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(rb5+s*rb6)))))
                        S = 1 + s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(sb5+s*(sb6+s*sb7))))))
                }
-               z := Float64frombits(Float64bits(x) & 0xffffffff00000000) // pseudo-single (20-bit) precison x
+               z := Float64frombits(Float64bits(x) & 0xffffffff00000000) // pseudo-single (20-bit) precision x
                r := Exp(-z*z-0.5625) * Exp((z-x)*(z+x)+R/S)
                if sign {
                        return 2 - r/x
index 269af0c..232d650 100644 (file)
@@ -15,7 +15,9 @@ import (
        "log"
        "net/http"
        "os"
+       "os/exec"
        "strconv"
+       "sync"
 )
 
 // hello world, the web server
@@ -28,14 +30,21 @@ func HelloServer(w http.ResponseWriter, req *http.Request) {
 
 // Simple counter server. POSTing to it will set the value.
 type Counter struct {
-       n int
+       mu sync.Mutex // protects n
+       n  int
 }
 
 // This makes Counter satisfy the expvar.Var interface, so we can export
 // it directly.
-func (ctr *Counter) String() string { return fmt.Sprintf("%d", ctr.n) }
+func (ctr *Counter) String() string {
+       ctr.mu.Lock()
+       defer ctr.mu.Unlock()
+       return fmt.Sprintf("%d", ctr.n)
+}
 
 func (ctr *Counter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
+       ctr.mu.Lock()
+       defer ctr.mu.Unlock()
        switch req.Method {
        case "GET":
                ctr.n++
@@ -95,54 +104,36 @@ func (ch Chan) ServeHTTP(w http.ResponseWriter, req *http.Request) {
 // exec a program, redirecting output
 func DateServer(rw http.ResponseWriter, req *http.Request) {
        rw.Header().Set("Content-Type", "text/plain; charset=utf-8")
-       r, w, err := os.Pipe()
-       if err != nil {
-               fmt.Fprintf(rw, "pipe: %s\n", err)
-               return
-       }
 
-       p, err := os.StartProcess("/bin/date", []string{"date"}, &os.ProcAttr{Files: []*os.File{nil, w, w}})
-       defer r.Close()
-       w.Close()
-       if err != nil {
-               fmt.Fprintf(rw, "fork/exec: %s\n", err)
-               return
-       }
-       io.Copy(rw, r)
-       wait, err := p.Wait(0)
+       date, err := exec.Command("/bin/date").Output()
        if err != nil {
-               fmt.Fprintf(rw, "wait: %s\n", err)
-               return
-       }
-       if !wait.Exited() || wait.ExitStatus() != 0 {
-               fmt.Fprintf(rw, "date: %v\n", wait)
+               http.Error(rw, err.Error(), 500)
                return
        }
+       rw.Write(date)
 }
 
 func Logger(w http.ResponseWriter, req *http.Request) {
-       log.Print(req.URL.Raw)
-       w.WriteHeader(404)
-       w.Write([]byte("oops"))
+       log.Print(req.URL)
+       http.Error(w, "oops", 404)
 }
 
-var webroot = flag.String("root", "/home/rsc", "web root directory")
+var webroot = flag.String("root", os.Getenv("HOME"), "web root directory")
 
 func main() {
        flag.Parse()
 
        // The counter is published as a variable directly.
        ctr := new(Counter)
-       http.Handle("/counter", ctr)
        expvar.Publish("counter", ctr)
-
+       http.Handle("/counter", ctr)
        http.Handle("/", http.HandlerFunc(Logger))
        http.Handle("/go/", http.StripPrefix("/go/", http.FileServer(http.Dir(*webroot))))
-       http.Handle("/flags", http.HandlerFunc(FlagServer))
-       http.Handle("/args", http.HandlerFunc(ArgServer))
-       http.Handle("/go/hello", http.HandlerFunc(HelloServer))
        http.Handle("/chan", ChanCreate())
-       http.Handle("/date", http.HandlerFunc(DateServer))
+       http.HandleFunc("/flags", FlagServer)
+       http.HandleFunc("/args", ArgServer)
+       http.HandleFunc("/go/hello", HelloServer)
+       http.HandleFunc("/date", DateServer)
        err := http.ListenAndServe(":12345", nil)
        if err != nil {
                log.Panicln("ListenAndServe:", err)
index 8c9c304..825b202 100644 (file)
@@ -13,7 +13,7 @@ import (
 )
 
 // If the ifindex is zero, interfaceTable returns mappings of all
-// network interfaces.  Otheriwse it returns a mapping of a specific
+// network interfaces.  Otherwise it returns a mapping of a specific
 // interface.
 func interfaceTable(ifindex int) ([]Interface, error) {
        tab, err := syscall.NetlinkRIB(syscall.RTM_GETLINK, syscall.AF_UNSPEC)
index 4876b3a..d4d7ce9 100644 (file)
@@ -9,7 +9,7 @@
 package net
 
 // If the ifindex is zero, interfaceTable returns mappings of all
-// network interfaces.  Otheriwse it returns a mapping of a specific
+// network interfaces.  Otherwise it returns a mapping of a specific
 // interface.
 func interfaceTable(ifindex int) ([]Interface, error) {
        return nil, nil
index d0c9753..4368b33 100644 (file)
@@ -56,7 +56,7 @@ func getInterfaceList() ([]syscall.InterfaceInfo, error) {
 }
 
 // If the ifindex is zero, interfaceTable returns mappings of all
-// network interfaces.  Otheriwse it returns a mapping of a specific
+// network interfaces.  Otherwise it returns a mapping of a specific
 // interface.
 func interfaceTable(ifindex int) ([]Interface, error) {
        ai, err := getAdapterList()
index a23bc5a..e5dd013 100644 (file)
@@ -5,7 +5,6 @@
 package net
 
 import (
-       "io"
        "runtime"
        "syscall"
        "testing"
@@ -67,7 +66,7 @@ func TestTCPListener(t *testing.T) {
                case syscall.AF_INET6:
                        testIPv6UnicastSocketOptions(t, fd)
                }
-               l1.(io.Closer).Close()
+               l1.Close()
        }
 }
 
@@ -112,7 +111,7 @@ func TestUDPListener(t *testing.T) {
                case syscall.AF_INET6:
                        testIPv6UnicastSocketOptions(t, fd)
                }
-               l1.(io.Closer).Close()
+               l1.Close()
        }
 }
 
@@ -134,7 +133,7 @@ func TestSimpleTCPListener(t *testing.T) {
                checkFirstListener(t, tt.net, tt.laddr+":"+port, l1)
                l2, err := Listen(tt.net, tt.laddr+":"+port)
                checkSecondListener(t, tt.net, tt.laddr+":"+port, err, l2)
-               l1.(io.Closer).Close()
+               l1.Close()
        }
 }
 
@@ -169,7 +168,7 @@ func TestSimpleUDPListener(t *testing.T) {
                checkFirstListener(t, tt.net, tt.laddr+":"+port, l1)
                l2, err := ListenPacket(tt.net, tt.laddr+":"+port)
                checkSecondListener(t, tt.net, tt.laddr+":"+port, err, l2)
-               l1.(io.Closer).Close()
+               l1.Close()
        }
 }
 
@@ -530,8 +529,9 @@ func TestProhibitionaryDialArgs(t *testing.T) {
        defer l.Close()
 
        for _, tt := range prohibitionaryDialArgTests {
-               _, err := Dial(tt.net, tt.addr+":"+port)
+               c, err := Dial(tt.net, tt.addr+":"+port)
                if err == nil {
+                       c.Close()
                        t.Fatalf("Dial(%q, %q) should fail", tt.net, tt.addr)
                }
        }
index e0b83b5..b88e494 100644 (file)
@@ -42,3 +42,21 @@ func NewSyscallError(syscall string, err error) error {
        }
        return &SyscallError{syscall, err}
 }
+
+// IsExist returns whether the error is known to report that a file or directory 
+// already exists. It is satisfied by ErrExist as well as some syscall errors.
+func IsExist(err error) bool {
+       return isExist(err)
+}
+
+// IsNotExist returns whether the error is known to report that a file or directory
+// does not exist. It is satisfied by ErrNotExist as well as some syscall errors.
+func IsNotExist(err error) bool {
+       return isNotExist(err)
+}
+
+// IsPermission returns whether the error is known to report that permission is denied.
+// It is satisfied by ErrPermission as well as some syscall errors.
+func IsPermission(err error) bool {
+       return isPermission(err)
+}
index 159d685..3c9dfb0 100644 (file)
@@ -4,24 +4,21 @@
 
 package os
 
-// IsExist returns whether the error is known to report that a file already exists.
-func IsExist(err error) bool {
+func isExist(err error) bool {
        if pe, ok := err.(*PathError); ok {
                err = pe.Err
        }
        return contains(err.Error(), " exists")
 }
 
-// IsNotExist returns whether the error is known to report that a file does not exist.
-func IsNotExist(err error) bool {
+func isNotExist(err error) bool {
        if pe, ok := err.(*PathError); ok {
                err = pe.Err
        }
        return contains(err.Error(), "does not exist")
 }
 
-// IsPermission returns whether the error is known to report that permission is denied.
-func IsPermission(err error) bool {
+func isPermission(err error) bool {
        if pe, ok := err.(*PathError); ok {
                err = pe.Err
        }
index d08ad5d..1685c1f 100644 (file)
@@ -8,27 +8,21 @@ package os
 
 import "syscall"
 
-// IsExist returns whether the error is known to report that a file already exists.
-// It is satisfied by ErrExist as well as some syscall errors.
-func IsExist(err error) bool {
+func isExist(err error) bool {
        if pe, ok := err.(*PathError); ok {
                err = pe.Err
        }
        return err == syscall.EEXIST || err == ErrExist
 }
 
-// IsNotExist returns whether the error is known to report that a file does not exist.
-// It is satisfied by ErrNotExist as well as some syscall errors.
-func IsNotExist(err error) bool {
+func isNotExist(err error) bool {
        if pe, ok := err.(*PathError); ok {
                err = pe.Err
        }
        return err == syscall.ENOENT || err == ErrNotExist
 }
 
-// IsPermission returns whether the error is known to report that permission is denied.
-// It is satisfied by ErrPermission as well as some syscall errors.
-func IsPermission(err error) bool {
+func isPermission(err error) bool {
        if pe, ok := err.(*PathError); ok {
                err = pe.Err
        }
index 8218f86..42f846f 100644 (file)
@@ -5,8 +5,10 @@
 package os_test
 
 import (
+       "fmt"
        "io/ioutil"
        "os"
+       "path/filepath"
        "testing"
 )
 
@@ -24,8 +26,56 @@ func TestErrIsExist(t *testing.T) {
                t.Fatal("Open should have failed")
                return
        }
-       if !os.IsExist(err) {
-               t.Fatalf("os.IsExist does not work as expected for %#v", err)
+       if s := checkErrorPredicate("os.IsExist", os.IsExist, err); s != "" {
+               t.Fatal(s)
                return
        }
 }
+
+func testErrNotExist(name string) string {
+       f, err := os.Open(name)
+       if err == nil {
+               f.Close()
+               return "Open should have failed"
+       }
+       if s := checkErrorPredicate("os.IsNotExist", os.IsNotExist, err); s != "" {
+               return s
+       }
+
+       err = os.Chdir(name)
+       if err == nil {
+               return "Chdir should have failed"
+       }
+       if s := checkErrorPredicate("os.IsNotExist", os.IsNotExist, err); s != "" {
+               return s
+       }
+       return ""
+}
+
+func TestErrIsNotExist(t *testing.T) {
+       tmpDir, err := ioutil.TempDir("", "_Go_ErrIsNotExist")
+       if err != nil {
+               t.Fatalf("create ErrIsNotExist tempdir: %s", err)
+               return
+       }
+       defer os.RemoveAll(tmpDir)
+
+       name := filepath.Join(tmpDir, "NotExists")
+       if s := testErrNotExist(name); s != "" {
+               t.Fatal(s)
+               return
+       }
+
+       name = filepath.Join(name, "NotExists2")
+       if s := testErrNotExist(name); s != "" {
+               t.Fatal(s)
+               return
+       }
+}
+
+func checkErrorPredicate(predName string, pred func(error) bool, err error) string {
+       if !pred(err) {
+               return fmt.Sprintf("%s does not work as expected for %#v", predName, err)
+       }
+       return ""
+}
index 84bf5ea..5d692b0 100644 (file)
@@ -6,30 +6,25 @@ package os
 
 import "syscall"
 
-// IsExist returns whether the error is known to report that a file already exists.
-// It is satisfied by ErrExist as well as some syscall errors.
-func IsExist(err error) bool {
+func isExist(err error) bool {
        if pe, ok := err.(*PathError); ok {
                err = pe.Err
        }
-       return err == syscall.EEXIST || err == syscall.ERROR_ALREADY_EXISTS ||
+       return err == syscall.ERROR_ALREADY_EXISTS ||
                err == syscall.ERROR_FILE_EXISTS || err == ErrExist
 }
 
-// IsNotExist returns whether the error is known to report that a file does not exist.
-// It is satisfied by ErrNotExist as well as some syscall errors.
-func IsNotExist(err error) bool {
+func isNotExist(err error) bool {
        if pe, ok := err.(*PathError); ok {
                err = pe.Err
        }
-       return err == syscall.ENOENT || err == ErrNotExist
+       return err == syscall.ERROR_FILE_NOT_FOUND ||
+               err == syscall.ERROR_PATH_NOT_FOUND || err == ErrNotExist
 }
 
-// IsPermission returns whether the error is known to report that permission is denied.
-// It is satisfied by ErrPermission as well as some syscall errors.
-func IsPermission(err error) bool {
+func isPermission(err error) bool {
        if pe, ok := err.(*PathError); ok {
                err = pe.Err
        }
-       return err == syscall.EACCES || err == syscall.EPERM || err == ErrPermission
+       return err == ErrPermission
 }
index a69680c..b8fb2e2 100644 (file)
@@ -179,7 +179,21 @@ func (f *File) pread(b []byte, off int64) (n int, err error) {
 // write writes len(b) bytes to the File.
 // It returns the number of bytes written and an error, if any.
 func (f *File) write(b []byte) (n int, err error) {
-       return syscall.Write(f.fd, b)
+       for {
+               m, err := syscall.Write(f.fd, b)
+               n += m
+
+               // If the syscall wrote some data but not all (short write)
+               // or it returned EINTR, then assume it stopped early for
+               // reasons that are uninteresting to the caller, and try again.
+               if 0 < m && m < len(b) || err == syscall.EINTR {
+                       b = b[m:]
+                       continue
+               }
+
+               return n, err
+       }
+       panic("not reached")
 }
 
 // pwrite writes len(b) bytes to the File starting at byte offset off.
index aa01669..8d3f677 100644 (file)
@@ -1045,3 +1045,22 @@ func TestSameFile(t *testing.T) {
                t.Errorf("files should be different")
        }
 }
+
+func TestDevNullFile(t *testing.T) {
+       f, err := Open(DevNull)
+       if err != nil {
+               t.Fatalf("Open(%s): %v", DevNull, err)
+       }
+       defer f.Close()
+       fi, err := f.Stat()
+       if err != nil {
+               t.Fatalf("Stat(%s): %v", DevNull, err)
+       }
+       name := filepath.Base(DevNull)
+       if fi.Name() != name {
+               t.Fatalf("wrong file name have %v want %v", fi.Name(), name)
+       }
+       if fi.Size() != 0 {
+               t.Fatalf("wrong file size have %d want 0", fi.Size())
+       }
+}
index 38d264f..db8b026 100644 (file)
@@ -7,6 +7,7 @@ package filepath
 import (
        "errors"
        "os"
+       "runtime"
        "sort"
        "strings"
        "unicode/utf8"
@@ -37,6 +38,9 @@ var ErrBadPattern = errors.New("syntax error in pattern")
 // The only possible returned error is ErrBadPattern, when pattern
 // is malformed.
 //
+// On Windows, escaping is disabled. Instead, '\\' is treated as
+// path separator.
+//
 func Match(pattern, name string) (matched bool, err error) {
 Pattern:
        for len(pattern) > 0 {
@@ -95,9 +99,11 @@ Scan:
        for i = 0; i < len(pattern); i++ {
                switch pattern[i] {
                case '\\':
-                       // error check handled in matchChunk: bad pattern.
-                       if i+1 < len(pattern) {
-                               i++
+                       if runtime.GOOS != "windows" {
+                               // error check handled in matchChunk: bad pattern.
+                               if i+1 < len(pattern) {
+                                       i++
+                               }
                        }
                case '[':
                        inrange = true
@@ -167,10 +173,12 @@ func matchChunk(chunk, s string) (rest string, ok bool, err error) {
                        chunk = chunk[1:]
 
                case '\\':
-                       chunk = chunk[1:]
-                       if len(chunk) == 0 {
-                               err = ErrBadPattern
-                               return
+                       if runtime.GOOS != "windows" {
+                               chunk = chunk[1:]
+                               if len(chunk) == 0 {
+                                       err = ErrBadPattern
+                                       return
+                               }
                        }
                        fallthrough
 
@@ -191,7 +199,7 @@ func getEsc(chunk string) (r rune, nchunk string, err error) {
                err = ErrBadPattern
                return
        }
-       if chunk[0] == '\\' {
+       if chunk[0] == '\\' && runtime.GOOS != "windows" {
                chunk = chunk[1:]
                if len(chunk) == 0 {
                        err = ErrBadPattern
index dc0fff2..e3d3658 100644 (file)
@@ -7,6 +7,7 @@ package filepath_test
 import (
        . "path/filepath"
        "runtime"
+       "strings"
        "testing"
 )
 
@@ -76,21 +77,26 @@ func errp(e error) string {
 }
 
 func TestMatch(t *testing.T) {
-       if runtime.GOOS == "windows" {
-               // XXX: Don't pass for windows.
-               return
-       }
        for _, tt := range matchTests {
-               ok, err := Match(tt.pattern, tt.s)
+               pattern := tt.pattern
+               s := tt.s
+               if runtime.GOOS == "windows" {
+                       if strings.Index(pattern, "\\") >= 0 {
+                               // no escape allowed on windows.
+                               continue
+                       }
+                       pattern = Clean(pattern)
+                       s = Clean(s)
+               }
+               ok, err := Match(pattern, s)
                if ok != tt.match || err != tt.err {
-                       t.Errorf("Match(%#q, %#q) = %v, %q want %v, %q", tt.pattern, tt.s, ok, errp(err), tt.match, errp(tt.err))
+                       t.Errorf("Match(%#q, %#q) = %v, %q want %v, %q", pattern, s, ok, errp(err), tt.match, errp(tt.err))
                }
        }
 }
 
 // contains returns true if vector contains the string s.
 func contains(vector []string, s string) bool {
-       s = ToSlash(s)
        for _, elem := range vector {
                if elem == s {
                        return true
@@ -110,18 +116,20 @@ var globTests = []struct {
 }
 
 func TestGlob(t *testing.T) {
-       if runtime.GOOS == "windows" {
-               // XXX: Don't pass for windows.
-               return
-       }
        for _, tt := range globTests {
-               matches, err := Glob(tt.pattern)
+               pattern := tt.pattern
+               result := tt.result
+               if runtime.GOOS == "windows" {
+                       pattern = Clean(pattern)
+                       result = Clean(result)
+               }
+               matches, err := Glob(pattern)
                if err != nil {
-                       t.Errorf("Glob error for %q: %s", tt.pattern, err)
+                       t.Errorf("Glob error for %q: %s", pattern, err)
                        continue
                }
-               if !contains(matches, tt.result) {
-                       t.Errorf("Glob(%#q) = %#v want %v", tt.pattern, matches, tt.result)
+               if !contains(matches, result) {
+                       t.Errorf("Glob(%#q) = %#v want %v", pattern, matches, result)
                }
        }
        for _, pattern := range []string{"no_match", "../*/no_match"} {
index 92e84f4..7fe18a9 100644 (file)
@@ -66,9 +66,10 @@ type Type interface {
        // It returns an empty string for unnamed types.
        Name() string
 
-       // PkgPath returns the type's package path.
-       // The package path is a full package import path like "encoding/base64".
-       // PkgPath returns an empty string for unnamed or predeclared types.
+       // PkgPath returns a named type's package path, that is, the import path
+       // that uniquely identifies the package, such as "encoding/base64".
+       // If the type was predeclared (string, error) or unnamed (*T, struct{}, []int),
+       // the package path will be the empty string.
        PkgPath() string
 
        // Size returns the number of bytes needed to store
@@ -351,11 +352,18 @@ type structType struct {
 
 // Method represents a single method.
 type Method struct {
-       PkgPath string // empty for uppercase Name
+       // Name is the method name.
+       // PkgPath is the package path that qualifies a lower case (unexported)
+       // method name.  It is empty for upper case (exported) method names.
+       // The combination of PkgPath and Name uniquely identifies a method
+       // in a method set. 
+       // See http://golang.org/ref/spec#Uniqueness_of_identifiers
        Name    string
-       Type    Type
-       Func    Value
-       Index   int
+       PkgPath string
+
+       Type  Type  // method type
+       Func  Value // func with receiver as first argument
+       Index int   // index for Type.Method
 }
 
 // High bit says whether type has
@@ -695,14 +703,20 @@ func (t *interfaceType) MethodByName(name string) (m Method, ok bool) {
        return
 }
 
+// A StructField describes a single field in a struct.
 type StructField struct {
-       PkgPath   string // empty for uppercase Name
-       Name      string
-       Type      Type
-       Tag       StructTag
-       Offset    uintptr
-       Index     []int
-       Anonymous bool
+       // Name is the field name.
+       // PkgPath is the package path that qualifies a lower case (unexported)
+       // field name.  It is empty for upper case (exported) field names.
+       // See http://golang.org/ref/spec#Uniqueness_of_identifiers
+       Name    string
+       PkgPath string
+
+       Type      Type      // field type
+       Tag       StructTag // field tag string
+       Offset    uintptr   // offset within struct, in bytes
+       Index     []int     // index sequence for Type.FieldByIndex
+       Anonymous bool      // is an anonymous field
 }
 
 // A StructTag is the tag string in a struct field.
index f3a0a7c..a12fcb2 100644 (file)
@@ -1624,6 +1624,15 @@ func MakeSlice(typ Type, len, cap int) Value {
        if typ.Kind() != Slice {
                panic("reflect.MakeSlice of non-slice type")
        }
+       if len < 0 {
+               panic("reflect.MakeSlice: negative len")
+       }
+       if cap < 0 {
+               panic("reflect.MakeSlice: negative cap")
+       }
+       if len > cap {
+               panic("reflect.MakeSlice: len > cap")
+       }
 
        // Declare slice so that gc can see the base pointer in it.
        var x []byte
index 31da3c8..62a4d55 100644 (file)
@@ -183,17 +183,21 @@ func quickSort(data Interface, a, b, maxDepth int) {
        }
 }
 
+// Sort sorts data.
+// It makes one call to data.Len to determine n, and O(n*log(n)) calls to
+// data.Less and data.Swap. The sort is not guaranteed to be stable.
 func Sort(data Interface) {
-       // Switch to heapsort if depth of 2*ceil(lg(n)) is reached.
+       // Switch to heapsort if depth of 2*ceil(lg(n+1)) is reached.
        n := data.Len()
        maxDepth := 0
-       for 1<<uint(maxDepth) < n {
+       for i := n; i > 0; i >>= 1 {
                maxDepth++
        }
        maxDepth *= 2
        quickSort(data, 0, n, maxDepth)
 }
 
+// IsSorted reports whether data is sorted.
 func IsSorted(data Interface) bool {
        n := data.Len()
        for i := n - 1; i > 0; i-- {
index ad0118e..9a720cf 100644 (file)
@@ -369,6 +369,7 @@ func (s *state) evalVariableNode(dot reflect.Value, v *parse.VariableNode, args
        // $x.Field has $x as the first ident, Field as the second. Eval the var, then the fields.
        value := s.varValue(v.Ident[0])
        if len(v.Ident) == 1 {
+               s.notAFunction(args, final)
                return value
        }
        return s.evalFieldChain(dot, value, v.Ident[1:], args, final)
index 70ab39c..5446027 100644 (file)
@@ -466,6 +466,10 @@ var execTests = []execTest{
        {"bug6b", "{{vfunc .V0 .V0}}", "vfunc", tVal, true},
        {"bug6c", "{{vfunc .V1 .V0}}", "vfunc", tVal, true},
        {"bug6d", "{{vfunc .V1 .V1}}", "vfunc", tVal, true},
+       // Legal parse but illegal execution: non-function should have no arguments.
+       {"bug7a", "{{3 2}}", "", tVal, false},
+       {"bug7b", "{{$x := 1}}{{$x 2}}", "", tVal, false},
+       {"bug7c", "{{$x := 1}}{{3 | $x}}", "", tVal, false},
 }
 
 func zeroArgs() string {
index 22dedc4..bd98bd0 100644 (file)
@@ -93,7 +93,7 @@ var multiExecTests = []execTest{
        {"invoke dot []int", `{{template "dot" .SI}}`, "[3 4 5]", tVal, true},
        {"invoke dotV", `{{template "dotV" .U}}`, "v", tVal, true},
        {"invoke nested int", `{{template "nested" .I}}`, "17", tVal, true},
-       {"variable declared by template", `{{template "nested" $x=.SI}},{{index $x 1}}`, "[3 4 5],4", tVal, true},
+       {"variable declared by template", `{{template "nested" $x:=.SI}},{{index $x 1}}`, "[3 4 5],4", tVal, true},
 
        // User-defined function: test argument evaluator.
        {"testFunc literal", `{{oneArg "joe"}}`, "oneArg=joe", tVal, true},
index 54e75ee..7705c0b 100644 (file)
@@ -347,6 +347,9 @@ Loop:
                default:
                        l.backup()
                        word := l.input[l.start:l.pos]
+                       if !l.atTerminator() {
+                               return l.errorf("unexpected character %+U", r)
+                       }
                        switch {
                        case key[word] > itemKeyword:
                                l.emit(key[word])
@@ -365,6 +368,28 @@ Loop:
        return lexInsideAction
 }
 
+// atTerminator reports whether the input is at valid termination character to
+// appear after an identifier. Mostly to catch cases like "$x+2" not being
+// acceptable without a space, in case we decide one day to implement
+// arithmetic.
+func (l *lexer) atTerminator() bool {
+       r := l.peek()
+       if isSpace(r) {
+               return true
+       }
+       switch r {
+       case eof, ',', '|', ':':
+               return true
+       }
+       // Does r start the delimiter? This can be ambiguous (with delim=="//", $x/2 will
+       // succeed but should fail) but only in extremely rare cases caused by willfully
+       // bad choice of delimiter.
+       if rd, _ := utf8.DecodeRuneInString(l.rightDelim); rd == r {
+               return true
+       }
+       return false
+}
+
 // lexChar scans a character constant. The initial quote is already
 // scanned.  Syntax checking is done by the parse.
 func lexChar(l *lexer) stateFn {
index d67b388..c0087b2 100644 (file)
@@ -326,7 +326,7 @@ func (t *Tree) pipeline(context string) (pipe *PipeNode) {
        for {
                if v := t.peek(); v.typ == itemVariable {
                        t.next()
-                       if next := t.peek(); next.typ == itemColonEquals || next.typ == itemChar {
+                       if next := t.peek(); next.typ == itemColonEquals || (next.typ == itemChar && next.val == ",") {
                                t.next()
                                variable := newVariable(v.val)
                                if len(variable.Ident) != 1 {
index 18c0a8b..b2e7882 100644 (file)
@@ -201,6 +201,10 @@ var parseTests = []parseTest{
                `{{range .X | .M}}"true"{{else}}"false"{{end}}`},
        {"range []int", "{{range .SI}}{{.}}{{end}}", noError,
                `{{range .SI}}{{.}}{{end}}`},
+       {"range 1 var", "{{range $x := .SI}}{{.}}{{end}}", noError,
+               `{{range $x := .SI}}{{.}}{{end}}`},
+       {"range 2 vars", "{{range $x, $y := .SI}}{{.}}{{end}}", noError,
+               `{{range $x, $y := .SI}}{{.}}{{end}}`},
        {"constants", "{{range .SI 1 -3.2i true false 'a'}}{{end}}", noError,
                `{{range .SI 1 -3.2i true false 'a'}}{{end}}`},
        {"template", "{{template `x`}}", noError,
@@ -226,6 +230,17 @@ var parseTests = []parseTest{
        {"invalid punctuation", "{{printf 3, 4}}", hasError, ""},
        {"multidecl outside range", "{{with $v, $u := 3}}{{end}}", hasError, ""},
        {"too many decls in range", "{{range $u, $v, $w := 3}}{{end}}", hasError, ""},
+       // Equals (and other chars) do not assignments make (yet).
+       {"bug0a", "{{$x := 0}}{{$x}}", noError, "{{$x := 0}}{{$x}}"},
+       {"bug0b", "{{$x = 1}}{{$x}}", hasError, ""},
+       {"bug0c", "{{$x ! 2}}{{$x}}", hasError, ""},
+       {"bug0d", "{{$x % 3}}{{$x}}", hasError, ""},
+       // Check the parse fails for := rather than comma.
+       {"bug0e", "{{range $x := $y := 3}}{{end}}", hasError, ""},
+       // Another bug: variable read must ignore following punctuation.
+       {"bug1a", "{{$x:=.}}{{$x!2}}", hasError, ""},                     // ! is just illegal here.
+       {"bug1b", "{{$x:=.}}{{$x+2}}", hasError, ""},                     // $x+2 should not parse as ($x) (+2).
+       {"bug1c", "{{$x:=.}}{{$x +2}}", noError, "{{$x := .}}{{$x +2}}"}, // It's OK with a space.
 }
 
 var builtins = map[string]interface{}{
index 3265211..9e2ca01 100755 (executable)
@@ -163,7 +163,7 @@ done
   done
 done
 
-runtime="chan.c cpuprof.c goc2c.c lock_futex.c lock_sema.c mcache.c mcentral.c mfinal.c mfixalloc.c mgc0.c mheap.c msize.c proc.c runtime.c runtime.h signal_unix.c malloc.h malloc.goc mprof.goc runtime1.goc sema.goc sigqueue.goc string.goc time.goc"
+runtime="chan.c cpuprof.c lock_futex.c lock_sema.c mcache.c mcentral.c mfinal.c mfixalloc.c mgc0.c mheap.c msize.c proc.c runtime.c runtime.h signal_unix.c malloc.h malloc.goc mprof.goc runtime1.goc sema.goc sigqueue.goc string.goc time.goc"
 for f in $runtime; do
   merge_c $f $f
 done
index 049f77e..dbcfa0f 100644 (file)
@@ -966,6 +966,11 @@ runtime_mstart(void* mp)
        }
 #endif
 
+       // Install signal handlers; after minit so that minit can
+       // prepare the thread to be able to handle the signals.
+       if(m == &runtime_m0)
+               runtime_initsig();
+
        schedule(nil);
        return nil;
 }
index d1ce26d..a0dbf80 100644 (file)
@@ -74,7 +74,7 @@ void
 runtime_panicstring(const char *s)
 {
        Eface err;
-       
+
        if(runtime_m()->gcing) {
                runtime_printf("panic: %s\n", s);
                runtime_throw("panic during gc");
@@ -101,7 +101,7 @@ runtime_goargs(void)
 {
        String *s;
        int32 i;
-       
+
        // for windows implementation see "os" package
        if(Windows)
                return;
@@ -119,7 +119,7 @@ runtime_goenvs_unix(void)
 {
        String *s;
        int32 i, n;
-       
+
        for(n=0; argv[argc+1+n] != 0; n++)
                ;
 
@@ -195,8 +195,6 @@ void
 runtime_check(void)
 {
        __go_register_gc_roots(&runtime_roots);
-
-       runtime_initsig ();
 }
 
 int64