Commit 9d49f4d0 by Ian Lance Taylor

Update Go library to release r60.1.

From-SVN: r179076
parent 270aae33
504f4e9b079c
fd30c132d1bd
The first line of this file holds the Mercurial revision number of the
last merge done from the master library sources.
......@@ -636,7 +636,8 @@ go_json_files = \
go/json/encode.go \
go/json/indent.go \
go/json/scanner.go \
go/json/stream.go
go/json/stream.go \
go/json/tags.go
go_log_files = \
go/log/log.go
......
......@@ -1037,7 +1037,8 @@ go_json_files = \
go/json/encode.go \
go/json/indent.go \
go/json/scanner.go \
go/json/stream.go
go/json/stream.go \
go/json/tags.go
go_log_files = \
go/log/log.go
......
// 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.
// type declarations
package test0
import "unsafe"
const pi = 3.1415
type (
N undeclared /* ERROR "undeclared" */
B bool
I int32
A [10]P
T struct {
x, y P
}
P *T
R (*R)
F func(A) I
Y interface {
f(A) I
}
S [](((P)))
M map[I]F
C chan<- I
)
type (
p1 pi /* ERROR "not a package" */ .foo
p2 unsafe.Pointer
)
type (
Pi pi /* ERROR "not a type" */
a /* DISABLED "illegal cycle" */ a
a /* ERROR "redeclared" */ int
// where the cycle error appears depends on the
// order in which declarations are processed
// (which depends on the order in which a map
// is iterated through)
b c
c /* DISABLED "illegal cycle" */ d
d e
e b
t *t
U V
V *W
W U
P1 *S2
P2 P1
S0 struct {
}
S1 struct {
a, b, c int
u, v, a /* ERROR "redeclared" */ float32
}
S2 struct {
U // anonymous field
// TODO(gri) recognize double-declaration below
// U /* ERROR "redeclared" */ int
}
S3 struct {
x S2
}
S4/* DISABLED "illegal cycle" */ struct {
S4
}
S5 struct {
S6
}
S6 /* DISABLED "illegal cycle" */ struct {
field S7
}
S7 struct {
S5
}
L1 []L1
L2 []int
A1 [10]int
A2 /* DISABLED "illegal cycle" */ [10]A2
A3 /* DISABLED "illegal cycle" */ [10]struct {
x A4
}
A4 [10]A3
F1 func()
F2 func(x, y, z float32)
F3 func(x, y, x /* ERROR "redeclared" */ float32)
F4 func() (x, y, x /* ERROR "redeclared" */ float32)
F5 func(x int) (x /* ERROR "redeclared" */ float32)
F6 func(x ...int)
I1 interface{}
I2 interface {
m1()
}
I3 interface {
m1()
m1 /* ERROR "redeclared" */ ()
}
I4 interface {
m1(x, y, x /* ERROR "redeclared" */ float32)
m2() (x, y, x /* ERROR "redeclared" */ float32)
m3(x int) (x /* ERROR "redeclared" */ float32)
}
I5 interface {
m1(I5)
}
I6 interface {
S0 /* ERROR "non-interface" */
}
I7 interface {
I1
I1
}
I8 /* DISABLED "illegal cycle" */ interface {
I8
}
I9 /* DISABLED "illegal cycle" */ interface {
I10
}
I10 interface {
I11
}
I11 interface {
I9
}
C1 chan int
C2 <-chan int
C3 chan<- C3
C4 chan C5
C5 chan C6
C6 chan C4
M1 map[Last]string
M2 map[string]M2
Last int
)
......@@ -221,6 +221,9 @@ In summary, a gob stream looks like
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
*/
package gob
......
......@@ -374,6 +374,8 @@ func TestCopyError(t *testing.T) {
}
}
/* This test doesn't work in gccgo's testing environment.
func TestDirUnix(t *testing.T) {
if skipTest(t) || runtime.GOOS == "windows" {
return
......@@ -402,6 +404,8 @@ func TestDirUnix(t *testing.T) {
runCgiTest(t, h, "GET /test.cgi HTTP/1.0\nHost: example.com\n\n", expectedMap)
}
*/
func TestDirWindows(t *testing.T) {
if skipTest(t) || runtime.GOOS != "windows" {
return
......
#!/usr/bin/perl
# 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.
#
# Test script run as a child process under cgi_test.go
use strict;
use Cwd;
my $q = MiniCGI->new;
my $params = $q->Vars;
if ($params->{"loc"}) {
print "Location: $params->{loc}\r\n\r\n";
exit(0);
}
my $NL = "\r\n";
$NL = "\n" if $params->{mode} eq "NL";
my $p = sub {
print "$_[0]$NL";
};
# With carriage returns
$p->("Content-Type: text/html");
$p->("X-CGI-Pid: $$");
$p->("X-Test-Header: X-Test-Value");
$p->("");
if ($params->{"bigresponse"}) {
for (1..1024) {
print "A" x 1024, "\n";
}
exit 0;
}
print "test=Hello CGI\n";
foreach my $k (sort keys %$params) {
print "param-$k=$params->{$k}\n";
}
foreach my $k (sort keys %ENV) {
my $clean_env = $ENV{$k};
$clean_env =~ s/[\n\r]//g;
print "env-$k=$clean_env\n";
}
# NOTE: don't call getcwd() for windows.
# msys return /c/go/src/... not C:\go\...
my $dir;
if ($^O eq 'MSWin32' || $^O eq 'msys') {
my $cmd = $ENV{'COMSPEC'} || 'c:\\windows\\system32\\cmd.exe';
$cmd =~ s!\\!/!g;
$dir = `$cmd /c cd`;
chomp $dir;
} else {
$dir = getcwd();
}
print "cwd=$dir\n";
# A minimal version of CGI.pm, for people without the perl-modules
# package installed. (CGI.pm used to be part of the Perl core, but
# some distros now bundle perl-base and perl-modules separately...)
package MiniCGI;
sub new {
my $class = shift;
return bless {}, $class;
}
sub Vars {
my $self = shift;
my $pairs;
if ($ENV{CONTENT_LENGTH}) {
$pairs = do { local $/; <STDIN> };
} else {
$pairs = $ENV{QUERY_STRING};
}
my $vars = {};
foreach my $kv (split(/&/, $pairs)) {
my ($k, $v) = split(/=/, $kv, 2);
$vars->{_urldecode($k)} = _urldecode($v);
}
return $vars;
}
sub _urldecode {
my $v = shift;
$v =~ tr/+/ /;
$v =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
return $v;
}
......@@ -140,6 +140,7 @@ type decodeState struct {
scan scanner
nextscan scanner // for calls to nextValue
savedError os.Error
tempstr string // scratch space to avoid some allocations
}
// errPhase is used for errors that should not happen unless
......@@ -470,6 +471,8 @@ func (d *decodeState) object(v reflect.Value) {
// Figure out field corresponding to key.
var subv reflect.Value
destring := false // whether the value is wrapped in a string to be decoded first
if mv.IsValid() {
elemType := mv.Type().Elem()
if !mapElem.IsValid() {
......@@ -486,7 +489,8 @@ func (d *decodeState) object(v reflect.Value) {
if isValidTag(key) {
for i := 0; i < sv.NumField(); i++ {
f = st.Field(i)
if f.Tag.Get("json") == key {
tagName, _ := parseTag(f.Tag.Get("json"))
if tagName == key {
ok = true
break
}
......@@ -508,6 +512,8 @@ func (d *decodeState) object(v reflect.Value) {
} else {
subv = sv.FieldByIndex(f.Index)
}
_, opts := parseTag(f.Tag.Get("json"))
destring = opts.Contains("string")
}
}
......@@ -520,8 +526,12 @@ func (d *decodeState) object(v reflect.Value) {
}
// Read value.
d.value(subv)
if destring {
d.value(reflect.ValueOf(&d.tempstr))
d.literalStore([]byte(d.tempstr), subv)
} else {
d.value(subv)
}
// Write value back to map;
// if using struct, subv points into struct already.
if mv.IsValid() {
......@@ -550,8 +560,12 @@ func (d *decodeState) literal(v reflect.Value) {
// Scan read one byte too far; back up.
d.off--
d.scan.undo(op)
item := d.data[start:d.off]
d.literalStore(d.data[start:d.off], v)
}
// literalStore decodes a literal stored in item into v.
func (d *decodeState) literalStore(item []byte, v reflect.Value) {
// Check for unmarshaler.
wantptr := item[0] == 'n' // null
unmarshaler, pv := d.indirect(v, wantptr)
......
......@@ -262,7 +262,10 @@ type All struct {
Float32 float32
Float64 float64
Foo string `json:"bar"`
Foo string `json:"bar"`
Foo2 string `json:"bar2,dummyopt"`
IntStr int64 `json:",string"`
PBool *bool
PInt *int
......@@ -331,6 +334,8 @@ var allValue = All{
Float32: 14.1,
Float64: 15.1,
Foo: "foo",
Foo2: "foo2",
IntStr: 42,
String: "16",
Map: map[string]Small{
"17": {Tag: "tag17"},
......@@ -391,6 +396,8 @@ var allValueIndent = `{
"Float32": 14.1,
"Float64": 15.1,
"bar": "foo",
"bar2": "foo2",
"IntStr": "42",
"PBool": null,
"PInt": null,
"PInt8": null,
......@@ -481,6 +488,8 @@ var pallValueIndent = `{
"Float32": 0,
"Float64": 0,
"bar": "",
"bar2": "",
"IntStr": "0",
"PBool": true,
"PInt": 2,
"PInt8": 3,
......
......@@ -4,6 +4,9 @@
// Package json implements encoding and decoding of JSON objects as defined in
// RFC 4627.
//
// See "JSON and Go" for an introduction to this package:
// http://blog.golang.org/2011/01/json-and-go.html
package json
import (
......@@ -14,7 +17,6 @@ import (
"runtime"
"sort"
"strconv"
"strings"
"unicode"
"utf8"
)
......@@ -59,6 +61,12 @@ import (
// // Note the leading comma.
// Field int `json:",omitempty"`
//
// The "string" option signals that a field is stored as JSON inside a
// JSON-encoded string. This extra level of encoding is sometimes
// used when communicating with JavaScript programs:
//
// Int64String int64 `json:",string"`
//
// The key name will be used if it's a non-empty string consisting of
// only Unicode letters, digits, dollar signs, hyphens, and underscores.
//
......@@ -221,6 +229,12 @@ func isEmptyValue(v reflect.Value) bool {
}
func (e *encodeState) reflectValue(v reflect.Value) {
e.reflectValueQuoted(v, false)
}
// reflectValueQuoted writes the value in v to the output.
// If quoted is true, the serialization is wrapped in a JSON string.
func (e *encodeState) reflectValueQuoted(v reflect.Value, quoted bool) {
if !v.IsValid() {
e.WriteString("null")
return
......@@ -238,26 +252,39 @@ func (e *encodeState) reflectValue(v reflect.Value) {
return
}
writeString := (*encodeState).WriteString
if quoted {
writeString = (*encodeState).string
}
switch v.Kind() {
case reflect.Bool:
x := v.Bool()
if x {
e.WriteString("true")
writeString(e, "true")
} else {
e.WriteString("false")
writeString(e, "false")
}
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
e.WriteString(strconv.Itoa64(v.Int()))
writeString(e, strconv.Itoa64(v.Int()))
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
e.WriteString(strconv.Uitoa64(v.Uint()))
writeString(e, strconv.Uitoa64(v.Uint()))
case reflect.Float32, reflect.Float64:
e.WriteString(strconv.FtoaN(v.Float(), 'g', -1, v.Type().Bits()))
writeString(e, strconv.FtoaN(v.Float(), 'g', -1, v.Type().Bits()))
case reflect.String:
e.string(v.String())
if quoted {
sb, err := Marshal(v.String())
if err != nil {
e.error(err)
}
e.string(string(sb))
} else {
e.string(v.String())
}
case reflect.Struct:
e.WriteByte('{')
......@@ -269,17 +296,14 @@ func (e *encodeState) reflectValue(v reflect.Value) {
if f.PkgPath != "" {
continue
}
tag, omitEmpty := f.Name, false
tag, omitEmpty, quoted := f.Name, false, false
if tv := f.Tag.Get("json"); tv != "" {
ss := strings.SplitN(tv, ",", 2)
if isValidTag(ss[0]) {
tag = ss[0]
}
if len(ss) > 1 {
// Currently the only option is omitempty,
// so parsing is trivial.
omitEmpty = ss[1] == "omitempty"
name, opts := parseTag(tv)
if isValidTag(name) {
tag = name
}
omitEmpty = opts.Contains("omitempty")
quoted = opts.Contains("string")
}
fieldValue := v.Field(i)
if omitEmpty && isEmptyValue(fieldValue) {
......@@ -292,7 +316,7 @@ func (e *encodeState) reflectValue(v reflect.Value) {
}
e.string(tag)
e.WriteByte(':')
e.reflectValue(fieldValue)
e.reflectValueQuoted(fieldValue, quoted)
}
e.WriteByte('}')
......@@ -380,7 +404,8 @@ func (sv stringValues) Swap(i, j int) { sv[i], sv[j] = sv[j], sv[i] }
func (sv stringValues) Less(i, j int) bool { return sv.get(i) < sv.get(j) }
func (sv stringValues) get(i int) string { return sv[i].String() }
func (e *encodeState) string(s string) {
func (e *encodeState) string(s string) (int, os.Error) {
len0 := e.Len()
e.WriteByte('"')
start := 0
for i := 0; i < len(s); {
......@@ -425,4 +450,5 @@ func (e *encodeState) string(s string) {
e.WriteString(s[start:])
}
e.WriteByte('"')
return e.Len() - len0, nil
}
......@@ -5,6 +5,8 @@
package json
import (
"bytes"
"reflect"
"testing"
)
......@@ -42,3 +44,39 @@ func TestOmitEmpty(t *testing.T) {
t.Errorf(" got: %s\nwant: %s\n", got, optionalsExpected)
}
}
type StringTag struct {
BoolStr bool `json:",string"`
IntStr int64 `json:",string"`
StrStr string `json:",string"`
}
var stringTagExpected = `{
"BoolStr": "true",
"IntStr": "42",
"StrStr": "\"xzbit\""
}`
func TestStringTag(t *testing.T) {
var s StringTag
s.BoolStr = true
s.IntStr = 42
s.StrStr = "xzbit"
got, err := MarshalIndent(&s, "", " ")
if err != nil {
t.Fatal(err)
}
if got := string(got); got != stringTagExpected {
t.Fatalf(" got: %s\nwant: %s\n", got, stringTagExpected)
}
// Verify that it round-trips.
var s2 StringTag
err = NewDecoder(bytes.NewBuffer(got)).Decode(&s2)
if err != nil {
t.Fatalf("Decode: %v", err)
}
if !reflect.DeepEqual(s, s2) {
t.Fatalf("decode didn't match.\nsource: %#v\nEncoded as:\n%s\ndecode: %#v", s, string(got), s2)
}
}
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package json
import (
"strings"
)
// tagOptions is the string following a comma in a struct field's "json"
// tag, or the empty string. It does not include the leading comma.
type tagOptions string
// parseTag splits a struct field's json tag into its name and
// comma-separated options.
func parseTag(tag string) (string, tagOptions) {
if idx := strings.Index(tag, ","); idx != -1 {
return tag[:idx], tagOptions(tag[idx+1:])
}
return tag, tagOptions("")
}
// Contains returns whether checks that a comma-separated list of options
// contains a particular substr flag. substr must be surrounded by a
// string boundary or commas.
func (o tagOptions) Contains(optionName string) bool {
if len(o) == 0 {
return false
}
s := string(o)
for s != "" {
var next string
i := strings.Index(s, ",")
if i >= 0 {
s, next = s[:i], s[i+1:]
}
if s == optionName {
return true
}
s = next
}
return false
}
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package json
import (
"testing"
)
func TestTagParsing(t *testing.T) {
name, opts := parseTag("field,foobar,foo")
if name != "field" {
t.Fatalf("name = %q, want field", name)
}
for _, tt := range []struct {
opt string
want bool
}{
{"foobar", true},
{"foo", true},
{"bar", false},
} {
if opts.Contains(tt.opt) != tt.want {
t.Errorf("Contains(%q) = %v", tt.opt, !tt.want)
}
}
}
......@@ -10,6 +10,9 @@
// A call to ValueOf returns a Value representing the run-time data.
// Zero takes a Type and returns a Value representing a zero value
// for that type.
//
// See "The Laws of Reflection" for an introduction to reflection in Go:
// http://blog.golang.org/2011/09/laws-of-reflection.html
package reflect
import (
......
......@@ -40,7 +40,7 @@ hg clone -r ${old_rev} ${repository} ${OLDDIR}
rm -rf ${NEWDIR}
hg clone -u release ${repository} ${NEWDIR}
new_rev=`cd ${NEWDIR} && hg log | sed 1q | sed -e 's/.*://'`
new_rev=`cd ${NEWDIR} && hg log -r release | sed 1q | sed -e 's/.*://'`
merge() {
name=$1
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment