Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
R
riscv-gcc-1
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
riscv-gcc-1
Commits
08a680a8
Commit
08a680a8
authored
Jun 25, 2012
by
Ian Lance Taylor
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
libgo: Update to Go 1.0.2 release.
From-SVN: r188943
parent
72de8622
Hide whitespace changes
Inline
Side-by-side
Showing
59 changed files
with
1088 additions
and
169 deletions
+1088
-169
libgo/MERGE
+1
-1
libgo/go/compress/flate/deflate.go
+20
-0
libgo/go/compress/flate/deflate_test.go
+44
-0
libgo/go/crypto/aes/const.go
+2
-2
libgo/go/crypto/ecdsa/ecdsa.go
+4
-2
libgo/go/crypto/rsa/pkcs1v15.go
+1
-0
libgo/go/crypto/tls/handshake_messages.go
+2
-2
libgo/go/crypto/x509/x509.go
+2
-2
libgo/go/debug/gosym/pclntab_test.go
+16
-2
libgo/go/encoding/base64/base64.go
+1
-1
libgo/go/encoding/base64/base64_test.go
+49
-0
libgo/go/encoding/gob/doc.go
+1
-1
libgo/go/encoding/json/decode.go
+12
-2
libgo/go/encoding/json/decode_test.go
+65
-0
libgo/go/encoding/json/encode.go
+3
-1
libgo/go/flag/flag.go
+3
-2
libgo/go/fmt/doc.go
+1
-1
libgo/go/go/ast/ast.go
+8
-6
libgo/go/go/ast/ast_test.go
+50
-0
libgo/go/go/build/build.go
+2
-2
libgo/go/go/parser/parser.go
+24
-18
libgo/go/go/parser/parser_test.go
+190
-5
libgo/go/go/printer/nodes.go
+12
-3
libgo/go/log/log.go
+1
-1
libgo/go/math/big/nat.go
+5
-5
libgo/go/math/big/nat_test.go
+18
-0
libgo/go/mime/multipart/multipart.go
+79
-36
libgo/go/mime/multipart/multipart_test.go
+213
-32
libgo/go/net/file.go
+2
-2
libgo/go/net/http/client.go
+5
-0
libgo/go/net/http/client_test.go
+25
-0
libgo/go/net/http/proxy_test.go
+30
-0
libgo/go/net/http/response.go
+6
-3
libgo/go/net/http/response_test.go
+15
-0
libgo/go/net/http/server.go
+1
-1
libgo/go/net/http/transfer.go
+4
-2
libgo/go/net/http/transport.go
+5
-1
libgo/go/net/mail/message.go
+6
-5
libgo/go/net/mail/message_test.go
+5
-0
libgo/go/net/url/url.go
+3
-2
libgo/go/net/url/url_test.go
+31
-0
libgo/go/os/exec/exec.go
+12
-6
libgo/go/path/filepath/path.go
+5
-2
libgo/go/path/filepath/path_plan9.go
+1
-1
libgo/go/path/filepath/path_test.go
+31
-0
libgo/go/regexp/regexp.go
+2
-2
libgo/go/regexp/syntax/parse.go
+5
-2
libgo/go/regexp/syntax/parse_test.go
+8
-0
libgo/go/runtime/extern.go
+3
-2
libgo/go/strconv/itoa.go
+6
-2
libgo/go/strings/example_test.go
+0
-1
libgo/go/text/template/exec.go
+7
-0
libgo/go/text/template/exec_test.go
+6
-0
libgo/go/time/sleep_test.go
+22
-0
libgo/go/unicode/tables.go
+3
-3
libgo/runtime/malloc.goc
+1
-0
libgo/runtime/mfinal.c
+1
-2
libgo/runtime/mgc0.c
+0
-1
libgo/runtime/time.goc
+8
-2
No files found.
libgo/MERGE
View file @
08a680a8
2ccfd4b451d3
5e806355a9e1
The first line of this file holds the Mercurial revision number of the
last merge done from the master library sources.
libgo/go/compress/flate/deflate.go
View file @
08a680a8
...
...
@@ -32,6 +32,7 @@ const (
hashSize
=
1
<<
hashBits
hashMask
=
(
1
<<
hashBits
)
-
1
hashShift
=
(
hashBits
+
minMatchLength
-
1
)
/
minMatchLength
maxHashOffset
=
1
<<
24
skipNever
=
math
.
MaxInt32
)
...
...
@@ -106,6 +107,25 @@ func (d *compressor) fillDeflate(b []byte) int {
d
.
blockStart
=
math
.
MaxInt32
}
d
.
hashOffset
+=
windowSize
if
d
.
hashOffset
>
maxHashOffset
{
delta
:=
d
.
hashOffset
-
1
d
.
hashOffset
-=
delta
d
.
chainHead
-=
delta
for
i
,
v
:=
range
d
.
hashPrev
{
if
v
>
delta
{
d
.
hashPrev
[
i
]
-=
delta
}
else
{
d
.
hashPrev
[
i
]
=
0
}
}
for
i
,
v
:=
range
d
.
hashHead
{
if
v
>
delta
{
d
.
hashHead
[
i
]
-=
delta
}
else
{
d
.
hashHead
[
i
]
=
0
}
}
}
}
n
:=
copy
(
d
.
window
[
d
.
windowEnd
:
],
b
)
d
.
windowEnd
+=
n
...
...
libgo/go/compress/flate/deflate_test.go
View file @
08a680a8
...
...
@@ -94,6 +94,50 @@ func TestDeflate(t *testing.T) {
}
}
// A sparseReader returns a stream consisting of 0s followed by 1<<16 1s.
// This tests missing hash references in a very large input.
type
sparseReader
struct
{
l
int64
cur
int64
}
func
(
r
*
sparseReader
)
Read
(
b
[]
byte
)
(
n
int
,
err
error
)
{
if
r
.
cur
>=
r
.
l
{
return
0
,
io
.
EOF
}
n
=
len
(
b
)
cur
:=
r
.
cur
+
int64
(
n
)
if
cur
>
r
.
l
{
n
-=
int
(
cur
-
r
.
l
)
cur
=
r
.
l
}
for
i
:=
range
b
[
0
:
n
]
{
if
r
.
cur
+
int64
(
i
)
>=
r
.
l
-
1
<<
16
{
b
[
i
]
=
1
}
else
{
b
[
i
]
=
0
}
}
r
.
cur
=
cur
return
}
func
TestVeryLongSparseChunk
(
t
*
testing
.
T
)
{
if
testing
.
Short
()
{
t
.
Logf
(
"skipping sparse chunk during short test"
)
return
}
w
,
err
:=
NewWriter
(
ioutil
.
Discard
,
1
)
if
err
!=
nil
{
t
.
Errorf
(
"NewWriter: %v"
,
err
)
return
}
if
_
,
err
=
io
.
Copy
(
w
,
&
sparseReader
{
l
:
23E8
});
err
!=
nil
{
t
.
Errorf
(
"Compress failed: %v"
,
err
)
return
}
}
type
syncBuffer
struct
{
buf
bytes
.
Buffer
mu
sync
.
RWMutex
...
...
libgo/go/crypto/aes/const.go
View file @
08a680a8
...
...
@@ -11,11 +11,11 @@ package aes
// http://www.csrc.nist.gov/publications/fips/fips197/fips-197.pdf
// AES is based on the mathematical behavior of binary polynomials
// (polynomials over GF(2)) modulo the irreducible polynomial x⁸ + x⁴ + x
²
+ x + 1.
// (polynomials over GF(2)) modulo the irreducible polynomial x⁸ + x⁴ + x
³
+ x + 1.
// Addition of these binary polynomials corresponds to binary xor.
// Reducing mod poly corresponds to binary xor with poly every
// time a 0x100 bit appears.
const
poly
=
1
<<
8
|
1
<<
4
|
1
<<
3
|
1
<<
1
|
1
<<
0
// x⁸ + x⁴ + x
²
+ x + 1
const
poly
=
1
<<
8
|
1
<<
4
|
1
<<
3
|
1
<<
1
|
1
<<
0
// x⁸ + x⁴ + x
³
+ x + 1
// Powers of x mod poly in GF(2).
var
powx
=
[
16
]
byte
{
...
...
libgo/go/crypto/ecdsa/ecdsa.go
View file @
08a680a8
...
...
@@ -66,7 +66,9 @@ func GenerateKey(c elliptic.Curve, rand io.Reader) (priv *PrivateKey, err error)
// hashToInt converts a hash value to an integer. There is some disagreement
// about how this is done. [NSA] suggests that this is done in the obvious
// manner, but [SECG] truncates the hash to the bit-length of the curve order
// first. We follow [SECG] because that's what OpenSSL does.
// first. We follow [SECG] because that's what OpenSSL does. Additionally,
// OpenSSL right shifts excess bits from the number if the hash is too large
// and we mirror that too.
func
hashToInt
(
hash
[]
byte
,
c
elliptic
.
Curve
)
*
big
.
Int
{
orderBits
:=
c
.
Params
()
.
N
.
BitLen
()
orderBytes
:=
(
orderBits
+
7
)
/
8
...
...
@@ -75,7 +77,7 @@ func hashToInt(hash []byte, c elliptic.Curve) *big.Int {
}
ret
:=
new
(
big
.
Int
)
.
SetBytes
(
hash
)
excess
:=
orderBytes
*
8
-
orderBits
excess
:=
len
(
hash
)
*
8
-
orderBits
if
excess
>
0
{
ret
.
Rsh
(
ret
,
uint
(
excess
))
}
...
...
libgo/go/crypto/rsa/pkcs1v15.go
View file @
08a680a8
...
...
@@ -151,6 +151,7 @@ func nonZeroRandomBytes(s []byte, rand io.Reader) (err error) {
var
hashPrefixes
=
map
[
crypto
.
Hash
][]
byte
{
crypto
.
MD5
:
{
0x30
,
0x20
,
0x30
,
0x0c
,
0x06
,
0x08
,
0x2a
,
0x86
,
0x48
,
0x86
,
0xf7
,
0x0d
,
0x02
,
0x05
,
0x05
,
0x00
,
0x04
,
0x10
},
crypto
.
SHA1
:
{
0x30
,
0x21
,
0x30
,
0x09
,
0x06
,
0x05
,
0x2b
,
0x0e
,
0x03
,
0x02
,
0x1a
,
0x05
,
0x00
,
0x04
,
0x14
},
crypto
.
SHA224
:
{
0x30
,
0x2d
,
0x30
,
0x0d
,
0x06
,
0x09
,
0x60
,
0x86
,
0x48
,
0x01
,
0x65
,
0x03
,
0x04
,
0x02
,
0x04
,
0x05
,
0x00
,
0x04
,
0x1c
},
crypto
.
SHA256
:
{
0x30
,
0x31
,
0x30
,
0x0d
,
0x06
,
0x09
,
0x60
,
0x86
,
0x48
,
0x01
,
0x65
,
0x03
,
0x04
,
0x02
,
0x01
,
0x05
,
0x00
,
0x04
,
0x20
},
crypto
.
SHA384
:
{
0x30
,
0x41
,
0x30
,
0x0d
,
0x06
,
0x09
,
0x60
,
0x86
,
0x48
,
0x01
,
0x65
,
0x03
,
0x04
,
0x02
,
0x02
,
0x05
,
0x00
,
0x04
,
0x30
},
crypto
.
SHA512
:
{
0x30
,
0x51
,
0x30
,
0x0d
,
0x06
,
0x09
,
0x60
,
0x86
,
0x48
,
0x01
,
0x65
,
0x03
,
0x04
,
0x02
,
0x03
,
0x05
,
0x00
,
0x04
,
0x40
},
...
...
libgo/go/crypto/tls/handshake_messages.go
View file @
08a680a8
...
...
@@ -563,7 +563,7 @@ func (m *certificateMsg) unmarshal(data []byte) bool {
if
len
(
d
)
<
4
{
return
false
}
certLen
:=
uint32
(
d
[
0
])
<<
24
|
uint32
(
d
[
1
])
<<
8
|
uint32
(
d
[
2
])
certLen
:=
uint32
(
d
[
0
])
<<
16
|
uint32
(
d
[
1
])
<<
8
|
uint32
(
d
[
2
])
if
uint32
(
len
(
d
))
<
3
+
certLen
{
return
false
}
...
...
@@ -575,7 +575,7 @@ func (m *certificateMsg) unmarshal(data []byte) bool {
m
.
certificates
=
make
([][]
byte
,
numCerts
)
d
=
data
[
7
:
]
for
i
:=
0
;
i
<
numCerts
;
i
++
{
certLen
:=
uint32
(
d
[
0
])
<<
24
|
uint32
(
d
[
1
])
<<
8
|
uint32
(
d
[
2
])
certLen
:=
uint32
(
d
[
0
])
<<
16
|
uint32
(
d
[
1
])
<<
8
|
uint32
(
d
[
2
])
m
.
certificates
[
i
]
=
d
[
3
:
3
+
certLen
]
d
=
d
[
3
+
certLen
:
]
}
...
...
libgo/go/crypto/x509/x509.go
View file @
08a680a8
...
...
@@ -388,10 +388,10 @@ func (c *Certificate) CheckSignature(algo SignatureAlgorithm, signed, signature
return
ErrUnsupportedAlgorithm
}
h
:=
hashType
.
New
()
if
h
==
nil
{
if
!
hashType
.
Available
()
{
return
ErrUnsupportedAlgorithm
}
h
:=
hashType
.
New
()
h
.
Write
(
signed
)
digest
:=
h
.
Sum
(
nil
)
...
...
libgo/go/debug/gosym/pclntab_test.go
View file @
08a680a8
...
...
@@ -7,14 +7,19 @@ package gosym
import
(
"debug/elf"
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"
"testing"
)
var
pclinetestBinary
string
var
(
pclineTempDir
string
pclinetestBinary
string
)
func
dotest
()
bool
{
// For now, only works on ELF platforms.
...
...
@@ -24,10 +29,18 @@ func dotest() bool {
if
pclinetestBinary
!=
""
{
return
true
}
var
err
error
pclineTempDir
,
err
=
ioutil
.
TempDir
(
""
,
"pclinetest"
)
if
err
!=
nil
{
panic
(
err
)
}
if
strings
.
Contains
(
pclineTempDir
,
" "
)
{
panic
(
"unexpected space in tempdir"
)
}
// This command builds pclinetest from pclinetest.asm;
// the resulting binary looks like it was built from pclinetest.s,
// but we have renamed it to keep it away from the go tool.
pclinetestBinary
=
os
.
TempDir
()
+
"/pclinetest"
pclinetestBinary
=
filepath
.
Join
(
pclineTempDir
,
"pclinetest"
)
command
:=
fmt
.
Sprintf
(
"go tool 6a -o %s.6 pclinetest.asm && go tool 6l -E main -o %s %s.6"
,
pclinetestBinary
,
pclinetestBinary
,
pclinetestBinary
)
cmd
:=
exec
.
Command
(
"sh"
,
"-c"
,
command
)
...
...
@@ -170,6 +183,7 @@ func TestPCLine(t *testing.T) {
if
!
dotest
()
{
return
}
defer
os
.
RemoveAll
(
pclineTempDir
)
f
,
tab
:=
crack
(
pclinetestBinary
,
t
)
text
:=
f
.
Section
(
".text"
)
...
...
libgo/go/encoding/base64/base64.go
View file @
08a680a8
...
...
@@ -318,7 +318,7 @@ func (d *decoder) Read(p []byte) (n int, err error) {
}
nn
,
d
.
err
=
io
.
ReadAtLeast
(
d
.
r
,
d
.
buf
[
d
.
nbuf
:
nn
],
4
-
d
.
nbuf
)
d
.
nbuf
+=
nn
if
d
.
nbuf
<
4
{
if
d
.
err
!=
nil
||
d
.
nbuf
<
4
{
return
0
,
d
.
err
}
...
...
libgo/go/encoding/base64/base64_test.go
View file @
08a680a8
...
...
@@ -6,9 +6,11 @@ package base64
import
(
"bytes"
"errors"
"io"
"io/ioutil"
"testing"
"time"
)
type
testpair
struct
{
...
...
@@ -226,3 +228,50 @@ func TestNewLineCharacters(t *testing.T) {
}
}
}
type
nextRead
struct
{
n
int
// bytes to return
err
error
// error to return
}
// faultInjectReader returns data from source, rate-limited
// and with the errors as written to nextc.
type
faultInjectReader
struct
{
source
string
nextc
<-
chan
nextRead
}
func
(
r
*
faultInjectReader
)
Read
(
p
[]
byte
)
(
int
,
error
)
{
nr
:=
<-
r
.
nextc
if
len
(
p
)
>
nr
.
n
{
p
=
p
[
:
nr
.
n
]
}
n
:=
copy
(
p
,
r
.
source
)
r
.
source
=
r
.
source
[
n
:
]
return
n
,
nr
.
err
}
// tests that we don't ignore errors from our underlying reader
func
TestDecoderIssue3577
(
t
*
testing
.
T
)
{
next
:=
make
(
chan
nextRead
,
10
)
wantErr
:=
errors
.
New
(
"my error"
)
next
<-
nextRead
{
5
,
nil
}
next
<-
nextRead
{
10
,
wantErr
}
d
:=
NewDecoder
(
StdEncoding
,
&
faultInjectReader
{
source
:
"VHdhcyBicmlsbGlnLCBhbmQgdGhlIHNsaXRoeSB0b3Zlcw=="
,
// twas brillig...
nextc
:
next
,
})
errc
:=
make
(
chan
error
)
go
func
()
{
_
,
err
:=
ioutil
.
ReadAll
(
d
)
errc
<-
err
}()
select
{
case
err
:=
<-
errc
:
if
err
!=
wantErr
{
t
.
Errorf
(
"got error %v; want %v"
,
err
,
wantErr
)
}
case
<-
time
.
After
(
5
*
time
.
Second
)
:
t
.
Errorf
(
"timeout; Decoder blocked without returning an error"
)
}
}
libgo/go/encoding/gob/doc.go
View file @
08a680a8
...
...
@@ -116,7 +116,7 @@ uninterpreted bytes of the value.
All other slices and arrays are sent as an unsigned count followed by that many
elements using the standard gob encoding for their type, recursively.
Maps are sent as an unsigned count followed by that man key, element
Maps are sent as an unsigned count followed by that man
y
key, element
pairs. Empty but non-nil maps are sent, so if the sender has allocated
a map, the receiver will allocate a map even no elements are
transmitted.
...
...
libgo/go/encoding/json/decode.go
View file @
08a680a8
...
...
@@ -273,9 +273,14 @@ func (d *decodeState) indirect(v reflect.Value, decodingNull bool) (Unmarshaler,
_
,
isUnmarshaler
=
v
.
Interface
()
.
(
Unmarshaler
)
}
// Load value from interface, but only if the result will be
// usefully addressable.
if
iv
:=
v
;
iv
.
Kind
()
==
reflect
.
Interface
&&
!
iv
.
IsNil
()
{
v
=
iv
.
Elem
()
continue
e
:=
iv
.
Elem
()
if
e
.
Kind
()
==
reflect
.
Ptr
&&
!
e
.
IsNil
()
&&
(
!
decodingNull
||
e
.
Elem
()
.
Kind
()
==
reflect
.
Ptr
)
{
v
=
e
continue
}
}
pv
:=
v
...
...
@@ -588,6 +593,11 @@ func (d *decodeState) literal(v reflect.Value) {
// produce more helpful error messages.
func
(
d
*
decodeState
)
literalStore
(
item
[]
byte
,
v
reflect
.
Value
,
fromQuoted
bool
)
{
// Check for unmarshaler.
if
len
(
item
)
==
0
{
//Empty string given
d
.
saveError
(
fmt
.
Errorf
(
"json: invalid use of ,string struct tag, trying to unmarshal %q into %v"
,
item
,
v
.
Type
()))
return
}
wantptr
:=
item
[
0
]
==
'n'
// null
unmarshaler
,
pv
:=
d
.
indirect
(
v
,
wantptr
)
if
unmarshaler
!=
nil
{
...
...
libgo/go/encoding/json/decode_test.go
View file @
08a680a8
...
...
@@ -638,3 +638,68 @@ func TestAnonymous(t *testing.T) {
t
.
Fatal
(
"Unmarshal: did set T.Y"
)
}
}
// Test that the empty string doesn't panic decoding when ,string is specified
// Issue 3450
func
TestEmptyString
(
t
*
testing
.
T
)
{
type
T2
struct
{
Number1
int
`json:",string"`
Number2
int
`json:",string"`
}
data
:=
`{"Number1":"1", "Number2":""}`
dec
:=
NewDecoder
(
strings
.
NewReader
(
data
))
var
t2
T2
err
:=
dec
.
Decode
(
&
t2
)
if
err
==
nil
{
t
.
Fatal
(
"Decode: did not return error"
)
}
if
t2
.
Number1
!=
1
{
t
.
Fatal
(
"Decode: did not set Number1"
)
}
}
func
intp
(
x
int
)
*
int
{
p
:=
new
(
int
)
*
p
=
x
return
p
}
func
intpp
(
x
*
int
)
**
int
{
pp
:=
new
(
*
int
)
*
pp
=
x
return
pp
}
var
interfaceSetTests
=
[]
struct
{
pre
interface
{}
json
string
post
interface
{}
}{
{
"foo"
,
`"bar"`
,
"bar"
},
{
"foo"
,
`2`
,
2.0
},
{
"foo"
,
`true`
,
true
},
{
"foo"
,
`null`
,
nil
},
{
nil
,
`null`
,
nil
},
{
new
(
int
),
`null`
,
nil
},
{(
*
int
)(
nil
),
`null`
,
nil
},
{
new
(
*
int
),
`null`
,
new
(
*
int
)},
{(
**
int
)(
nil
),
`null`
,
nil
},
{
intp
(
1
),
`null`
,
nil
},
{
intpp
(
nil
),
`null`
,
intpp
(
nil
)},
{
intpp
(
intp
(
1
)),
`null`
,
intpp
(
nil
)},
}
func
TestInterfaceSet
(
t
*
testing
.
T
)
{
for
_
,
tt
:=
range
interfaceSetTests
{
b
:=
struct
{
X
interface
{}
}{
tt
.
pre
}
blob
:=
`{"X":`
+
tt
.
json
+
`}`
if
err
:=
Unmarshal
([]
byte
(
blob
),
&
b
);
err
!=
nil
{
t
.
Errorf
(
"Unmarshal %#q: %v"
,
blob
,
err
)
continue
}
if
!
reflect
.
DeepEqual
(
b
.
X
,
tt
.
post
)
{
t
.
Errorf
(
"Unmarshal %#q into %#v: X=%#v, want %#v"
,
blob
,
tt
.
pre
,
b
.
X
,
tt
.
post
)
}
}
}
libgo/go/encoding/json/encode.go
View file @
08a680a8
...
...
@@ -96,7 +96,7 @@ import (
//
// Channel, complex, and function values cannot be encoded in JSON.
// Attempting to encode such a value causes Marshal to return
// an
Invali
dTypeError.
// an
Unsupporte
dTypeError.
//
// JSON cannot represent cyclic data structures and Marshal does not
// handle them. Passing cyclic structures to Marshal will result in
...
...
@@ -157,6 +157,8 @@ type Marshaler interface {
MarshalJSON
()
([]
byte
,
error
)
}
// An UnsupportedTypeError is returned by Marshal when attempting
// to encode an unsupported value type.
type
UnsupportedTypeError
struct
{
Type
reflect
.
Type
}
...
...
libgo/go/flag/flag.go
View file @
08a680a8
...
...
@@ -620,8 +620,9 @@ func (f *FlagSet) Var(value Value, name string, usage string) {
flag
:=
&
Flag
{
name
,
usage
,
value
,
value
.
String
()}
_
,
alreadythere
:=
f
.
formal
[
name
]
if
alreadythere
{
fmt
.
Fprintf
(
f
.
out
(),
"%s flag redefined: %s
\n
"
,
f
.
name
,
name
)
panic
(
"flag redefinition"
)
// Happens only if flags are declared with identical names
msg
:=
fmt
.
Sprintf
(
"%s flag redefined: %s"
,
f
.
name
,
name
)
fmt
.
Fprintln
(
f
.
out
(),
msg
)
panic
(
msg
)
// Happens only if flags are declared with identical names
}
if
f
.
formal
==
nil
{
f
.
formal
=
make
(
map
[
string
]
*
Flag
)
...
...
libgo/go/fmt/doc.go
View file @
08a680a8
...
...
@@ -136,7 +136,7 @@
Fscanf and Fscanln read from a specified io.Reader; Sscan,
Sscanf and Sscanln read from an argument string. Scanln,
Fscanln and Sscanln stop scanning at a newline and require that
the items be followed by one; S
s
canf, Fscanf and Sscanf require
the items be followed by one; Scanf, Fscanf and Sscanf require
newlines in the input to match newlines in the format; the other
routines treat newlines as spaces.
...
...
libgo/go/go/ast/ast.go
View file @
08a680a8
...
...
@@ -87,8 +87,12 @@ func stripTrailingWhitespace(s string) string {
return
s
[
0
:
i
]
}
// Text returns the text of the comment,
// with the comment markers - //, /*, and */ - removed.
// Text returns the text of the comment.
// Comment markers (//, /*, and */), the first space of a line comment, and
// leading and trailing empty lines are removed. Multiple empty lines are
// reduced to one, and trailing space on lines is trimmed. Unless the result
// is empty, it is newline-terminated.
//
func
(
g
*
CommentGroup
)
Text
()
string
{
if
g
==
nil
{
return
""
...
...
@@ -104,11 +108,9 @@ func (g *CommentGroup) Text() string {
// The parser has given us exactly the comment text.
switch
c
[
1
]
{
case
'/'
:
//-style comment
//-style comment
(no newline at the end)
c
=
c
[
2
:
]
// Remove leading space after //, if there is one.
// TODO(gri) This appears to be necessary in isolated
// cases (bignum.RatFromString) - why?
// strip first space - required for Example tests
if
len
(
c
)
>
0
&&
c
[
0
]
==
' '
{
c
=
c
[
1
:
]
}
...
...
libgo/go/go/ast/ast_test.go
0 → 100644
View file @
08a680a8
// 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
ast
import
(
"testing"
)
var
comments
=
[]
struct
{
list
[]
string
text
string
}{
{[]
string
{
"//"
},
""
},
{[]
string
{
"// "
},
""
},
{[]
string
{
"//"
,
"//"
,
"// "
},
""
},
{[]
string
{
"// foo "
},
"foo
\n
"
},
{[]
string
{
"//"
,
"//"
,
"// foo"
},
"foo
\n
"
},
{[]
string
{
"// foo bar "
},
"foo bar
\n
"
},
{[]
string
{
"// foo"
,
"// bar"
},
"foo
\n
bar
\n
"
},
{[]
string
{
"// foo"
,
"//"
,
"//"
,
"//"
,
"// bar"
},
"foo
\n\n
bar
\n
"
},
{[]
string
{
"// foo"
,
"/* bar */"
},
"foo
\n
bar
\n
"
},
{[]
string
{
"//"
,
"//"
,
"//"
,
"// foo"
,
"//"
,
"//"
,
"//"
},
"foo
\n
"
},
{[]
string
{
"/**/"
},
""
},
{[]
string
{
"/* */"
},
""
},
{[]
string
{
"/**/"
,
"/**/"
,
"/* */"
},
""
},
{[]
string
{
"/* Foo */"
},
" Foo
\n
"
},
{[]
string
{
"/* Foo Bar */"
},
" Foo Bar
\n
"
},
{[]
string
{
"/* Foo*/"
,
"/* Bar*/"
},
" Foo
\n
Bar
\n
"
},
{[]
string
{
"/* Foo*/"
,
"/**/"
,
"/**/"
,
"/**/"
,
"// Bar"
},
" Foo
\n\n
Bar
\n
"
},
{[]
string
{
"/* Foo*/"
,
"/*
\n
*/"
,
"//"
,
"/*
\n
*/"
,
"// Bar"
},
" Foo
\n\n
Bar
\n
"
},
{[]
string
{
"/* Foo*/"
,
"// Bar"
},
" Foo
\n
Bar
\n
"
},
{[]
string
{
"/* Foo
\n
Bar*/"
},
" Foo
\n
Bar
\n
"
},
}
func
TestCommentText
(
t
*
testing
.
T
)
{
for
i
,
c
:=
range
comments
{
list
:=
make
([]
*
Comment
,
len
(
c
.
list
))
for
i
,
s
:=
range
c
.
list
{
list
[
i
]
=
&
Comment
{
Text
:
s
}
}
text
:=
(
&
CommentGroup
{
list
})
.
Text
()
if
text
!=
c
.
text
{
t
.
Errorf
(
"case %d: got %q; expected %q"
,
i
,
text
,
c
.
text
)
}
}
}
libgo/go/go/build/build.go
View file @
08a680a8
...
...
@@ -68,7 +68,7 @@ type Context struct {
// ReadDir returns a slice of os.FileInfo, sorted by Name,
// describing the content of the named directory.
// If ReadDir is nil, Import uses io.ReadDir.
// If ReadDir is nil, Import uses io
util
.ReadDir.
ReadDir
func
(
dir
string
)
(
fi
[]
os
.
FileInfo
,
err
error
)
// OpenFile opens a file (not a directory) for reading.
...
...
@@ -339,7 +339,7 @@ func (e *NoGoError) Error() string {
// - 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 a
lso returns
a non-nil
// If an error occurs, Import returns a non-nil error a
nd
a non-nil
// *Package containing partial information.
//
func
(
ctxt
*
Context
)
Import
(
path
string
,
srcDir
string
,
mode
ImportMode
)
(
*
Package
,
error
)
{
...
...
libgo/go/go/parser/parser.go
View file @
08a680a8
...
...
@@ -267,13 +267,13 @@ func (p *parser) consumeComment() (comment *ast.Comment, endline int) {
// Consume a group of adjacent comments, add it to the parser's
// comments list, and return it together with the line at which
// the last comment in the group ends. A
n empty line or non-comment
//
token terminates
a comment group.
// the last comment in the group ends. A
non-comment token or n
//
empty lines terminate
a comment group.
//
func
(
p
*
parser
)
consumeCommentGroup
()
(
comments
*
ast
.
CommentGroup
,
endline
int
)
{
func
(
p
*
parser
)
consumeCommentGroup
(
n
int
)
(
comments
*
ast
.
CommentGroup
,
endline
int
)
{
var
list
[]
*
ast
.
Comment
endline
=
p
.
file
.
Line
(
p
.
pos
)
for
p
.
tok
==
token
.
COMMENT
&&
endline
+
1
>=
p
.
file
.
Line
(
p
.
pos
)
{
for
p
.
tok
==
token
.
COMMENT
&&
p
.
file
.
Line
(
p
.
pos
)
<=
endline
+
n
{
var
comment
*
ast
.
Comment
comment
,
endline
=
p
.
consumeComment
()
list
=
append
(
list
,
comment
)
...
...
@@ -314,7 +314,7 @@ func (p *parser) next() {
if
p
.
file
.
Line
(
p
.
pos
)
==
line
{
// The comment is on same line as the previous token; it
// cannot be a lead comment but may be a line comment.
comment
,
endline
=
p
.
consumeCommentGroup
()
comment
,
endline
=
p
.
consumeCommentGroup
(
0
)
if
p
.
file
.
Line
(
p
.
pos
)
!=
endline
{
// The next token is on a different line, thus
// the last comment group is a line comment.
...
...
@@ -325,7 +325,7 @@ func (p *parser) next() {
// consume successor comments, if any
endline
=
-
1
for
p
.
tok
==
token
.
COMMENT
{
comment
,
endline
=
p
.
consumeCommentGroup
()
comment
,
endline
=
p
.
consumeCommentGroup
(
1
)
}
if
endline
+
1
==
p
.
file
.
Line
(
p
.
pos
)
{
...
...
@@ -627,10 +627,10 @@ func (p *parser) parseFieldDecl(scope *ast.Scope) *ast.Field {
doc
:=
p
.
leadComment
//
fields
//
FieldDecl
list
,
typ
:=
p
.
parseVarList
(
false
)
//
optional t
ag
//
T
ag
var
tag
*
ast
.
BasicLit
if
p
.
tok
==
token
.
STRING
{
tag
=
&
ast
.
BasicLit
{
ValuePos
:
p
.
pos
,
Kind
:
p
.
tok
,
Value
:
p
.
lit
}
...
...
@@ -645,7 +645,6 @@ func (p *parser) parseFieldDecl(scope *ast.Scope) *ast.Field {
}
else
{
// ["*"] TypeName (AnonymousField)
typ
=
list
[
0
]
// we always have at least one element
p
.
resolve
(
typ
)
if
n
:=
len
(
list
);
n
>
1
||
!
isTypeName
(
deref
(
typ
))
{
pos
:=
typ
.
Pos
()
p
.
errorExpected
(
pos
,
"anonymous field"
)
...
...
@@ -657,6 +656,7 @@ func (p *parser) parseFieldDecl(scope *ast.Scope) *ast.Field {
field
:=
&
ast
.
Field
{
Doc
:
doc
,
Names
:
idents
,
Type
:
typ
,
Tag
:
tag
,
Comment
:
p
.
lineComment
}
p
.
declare
(
field
,
nil
,
scope
,
ast
.
Var
,
idents
...
)
p
.
resolve
(
typ
)
return
field
}
...
...
@@ -699,12 +699,15 @@ func (p *parser) parsePointerType() *ast.StarExpr {
return
&
ast
.
StarExpr
{
Star
:
star
,
X
:
base
}
}
// If the result is an identifier, it is not resolved.
func
(
p
*
parser
)
tryVarType
(
isParam
bool
)
ast
.
Expr
{
if
isParam
&&
p
.
tok
==
token
.
ELLIPSIS
{
pos
:=
p
.
pos
p
.
next
()
typ
:=
p
.
tryIdentOrType
(
isParam
)
// don't use parseType so we can provide better error message
if
typ
==
nil
{
if
typ
!=
nil
{
p
.
resolve
(
typ
)
}
else
{
p
.
error
(
pos
,
"'...' parameter is missing type"
)
typ
=
&
ast
.
BadExpr
{
From
:
pos
,
To
:
p
.
pos
}
}
...
...
@@ -713,6 +716,7 @@ func (p *parser) tryVarType(isParam bool) ast.Expr {
return
p
.
tryIdentOrType
(
false
)
}
// If the result is an identifier, it is not resolved.
func
(
p
*
parser
)
parseVarType
(
isParam
bool
)
ast
.
Expr
{
typ
:=
p
.
tryVarType
(
isParam
)
if
typ
==
nil
{
...
...
@@ -724,6 +728,7 @@ func (p *parser) parseVarType(isParam bool) ast.Expr {
return
typ
}
// If any of the results are identifiers, they are not resolved.
func
(
p
*
parser
)
parseVarList
(
isParam
bool
)
(
list
[]
ast
.
Expr
,
typ
ast
.
Expr
)
{
if
p
.
trace
{
defer
un
(
trace
(
p
,
"VarList"
))
...
...
@@ -744,9 +749,7 @@ func (p *parser) parseVarList(isParam bool) (list []ast.Expr, typ ast.Expr) {
}
// if we had a list of identifiers, it must be followed by a type
if
typ
=
p
.
tryVarType
(
isParam
);
typ
!=
nil
{
p
.
resolve
(
typ
)
}
typ
=
p
.
tryVarType
(
isParam
)
return
}
...
...
@@ -756,7 +759,10 @@ func (p *parser) parseParameterList(scope *ast.Scope, ellipsisOk bool) (params [
defer
un
(
trace
(
p
,
"ParameterList"
))
}
// ParameterDecl
list
,
typ
:=
p
.
parseVarList
(
ellipsisOk
)
// analyze case
if
typ
!=
nil
{
// IdentifierList Type
idents
:=
p
.
makeIdentList
(
list
)
...
...
@@ -765,10 +771,10 @@ func (p *parser) parseParameterList(scope *ast.Scope, ellipsisOk bool) (params [
// Go spec: The scope of an identifier denoting a function
// parameter or result variable is the function body.
p
.
declare
(
field
,
nil
,
scope
,
ast
.
Var
,
idents
...
)
p
.
resolve
(
typ
)
if
p
.
tok
==
token
.
COMMA
{
p
.
next
()
}
for
p
.
tok
!=
token
.
RPAREN
&&
p
.
tok
!=
token
.
EOF
{
idents
:=
p
.
parseIdentList
()
typ
:=
p
.
parseVarType
(
ellipsisOk
)
...
...
@@ -777,18 +783,18 @@ func (p *parser) parseParameterList(scope *ast.Scope, ellipsisOk bool) (params [
// Go spec: The scope of an identifier denoting a function
// parameter or result variable is the function body.
p
.
declare
(
field
,
nil
,
scope
,
ast
.
Var
,
idents
...
)
p
.
resolve
(
typ
)
if
!
p
.
atComma
(
"parameter list"
)
{
break
}
p
.
next
()
}
}
else
{
// Type { "," Type } (anonymous parameters)
params
=
make
([]
*
ast
.
Field
,
len
(
list
))
for
i
,
x
:=
range
list
{
p
.
resolve
(
x
)
params
[
i
]
=
&
ast
.
Field
{
Type
:
x
}
for
i
,
typ
:=
range
list
{
p
.
resolve
(
typ
)
params
[
i
]
=
&
ast
.
Field
{
Type
:
typ
}
}
}
...
...
libgo/go/go/parser/parser_test.go
View file @
08a680a8
...
...
@@ -5,10 +5,12 @@
package
parser
import
(
"bytes"
"fmt"
"go/ast"
"go/token"
"os"
"strings"
"testing"
)
...
...
@@ -25,7 +27,7 @@ func TestParse(t *testing.T) {
for
_
,
filename
:=
range
validFiles
{
_
,
err
:=
ParseFile
(
fset
,
filename
,
nil
,
DeclarationErrors
)
if
err
!=
nil
{
t
.
Error
f
(
"ParseFile(%s): %v"
,
filename
,
err
)
t
.
Fatal
f
(
"ParseFile(%s): %v"
,
filename
,
err
)
}
}
}
...
...
@@ -70,7 +72,7 @@ func TestParseExpr(t *testing.T) {
src
:=
"a + b"
x
,
err
:=
ParseExpr
(
src
)
if
err
!=
nil
{
t
.
Error
f
(
"ParseExpr(%s): %v"
,
src
,
err
)
t
.
Fatal
f
(
"ParseExpr(%s): %v"
,
src
,
err
)
}
// sanity check
if
_
,
ok
:=
x
.
(
*
ast
.
BinaryExpr
);
!
ok
{
...
...
@@ -81,7 +83,7 @@ func TestParseExpr(t *testing.T) {
src
=
"a + *"
_
,
err
=
ParseExpr
(
src
)
if
err
==
nil
{
t
.
Error
f
(
"ParseExpr(%s): %v"
,
src
,
err
)
t
.
Fatal
f
(
"ParseExpr(%s): %v"
,
src
,
err
)
}
// it must not crash
...
...
@@ -93,7 +95,7 @@ func TestParseExpr(t *testing.T) {
func
TestColonEqualsScope
(
t
*
testing
.
T
)
{
f
,
err
:=
ParseFile
(
fset
,
""
,
`package p; func f() { x, y, z := x, y, z }`
,
0
)
if
err
!=
nil
{
t
.
Errorf
(
"parse: %s"
,
err
)
t
.
Fatal
(
err
)
}
// RHS refers to undefined globals; LHS does not.
...
...
@@ -115,7 +117,7 @@ func TestColonEqualsScope(t *testing.T) {
func
TestVarScope
(
t
*
testing
.
T
)
{
f
,
err
:=
ParseFile
(
fset
,
""
,
`package p; func f() { var x, y, z = x, y, z }`
,
0
)
if
err
!=
nil
{
t
.
Errorf
(
"parse: %s"
,
err
)
t
.
Fatal
(
err
)
}
// RHS refers to undefined globals; LHS does not.
...
...
@@ -133,6 +135,67 @@ func TestVarScope(t *testing.T) {
}
}
func
TestUnresolved
(
t
*
testing
.
T
)
{
f
,
err
:=
ParseFile
(
fset
,
""
,
`
package p
//
func f1a(int)
func f2a(byte, int, float)
func f3a(a, b int, c float)
func f4a(...complex)
func f5a(a s1a, b ...complex)
//
func f1b(*int)
func f2b([]byte, (int), *float)
func f3b(a, b *int, c []float)
func f4b(...*complex)
func f5b(a s1a, b ...[]complex)
//
type s1a struct { int }
type s2a struct { byte; int; s1a }
type s3a struct { a, b int; c float }
//
type s1b struct { *int }
type s2b struct { byte; int; *float }
type s3b struct { a, b *s3b; c []float }
`
,
0
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
want
:=
"int "
+
// f1a
"byte int float "
+
// f2a
"int float "
+
// f3a
"complex "
+
// f4a
"complex "
+
// f5a
//
"int "
+
// f1b
"byte int float "
+
// f2b
"int float "
+
// f3b
"complex "
+
// f4b
"complex "
+
// f5b
//
"int "
+
// s1a
"byte int "
+
// s2a
"int float "
+
// s3a
//
"int "
+
// s1a
"byte int float "
+
// s2a
"float "
// s3a
// collect unresolved identifiers
var
buf
bytes
.
Buffer
for
_
,
u
:=
range
f
.
Unresolved
{
buf
.
WriteString
(
u
.
Name
)
buf
.
WriteByte
(
' '
)
}
got
:=
buf
.
String
()
if
got
!=
want
{
t
.
Errorf
(
"
\n
got: %s
\n
want: %s"
,
got
,
want
)
}
}
var
imports
=
map
[
string
]
bool
{
`"a"`
:
true
,
"`a`"
:
true
,
...
...
@@ -177,3 +240,125 @@ func TestImports(t *testing.T) {
}
}
}
func
TestCommentGroups
(
t
*
testing
.
T
)
{
f
,
err
:=
ParseFile
(
fset
,
""
,
`
package p /* 1a */ /* 1b */ /* 1c */ // 1d
/* 2a
*/
// 2b
const pi = 3.1415
/* 3a */ // 3b
/* 3c */ const e = 2.7182
// Example from issue 3139
func ExampleCount() {
fmt.Println(strings.Count("cheese", "e"))
fmt.Println(strings.Count("five", "")) // before & after each rune
// Output:
// 3
// 5
}
`
,
ParseComments
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
expected
:=
[][]
string
{
{
"/* 1a */"
,
"/* 1b */"
,
"/* 1c */"
,
"// 1d"
},
{
"/* 2a
\n
*/"
,
"// 2b"
},
{
"/* 3a */"
,
"// 3b"
,
"/* 3c */"
},
{
"// Example from issue 3139"
},
{
"// before & after each rune"
},
{
"// Output:"
,
"// 3"
,
"// 5"
},
}
if
len
(
f
.
Comments
)
!=
len
(
expected
)
{
t
.
Fatalf
(
"got %d comment groups; expected %d"
,
len
(
f
.
Comments
),
len
(
expected
))
}
for
i
,
exp
:=
range
expected
{
got
:=
f
.
Comments
[
i
]
.
List
if
len
(
got
)
!=
len
(
exp
)
{
t
.
Errorf
(
"got %d comments in group %d; expected %d"
,
len
(
got
),
i
,
len
(
exp
))
continue
}
for
j
,
exp
:=
range
exp
{
got
:=
got
[
j
]
.
Text
if
got
!=
exp
{
t
.
Errorf
(
"got %q in group %d; expected %q"
,
got
,
i
,
exp
)
}
}
}
}
func
getField
(
file
*
ast
.
File
,
fieldname
string
)
*
ast
.
Field
{
parts
:=
strings
.
Split
(
fieldname
,
"."
)
for
_
,
d
:=
range
file
.
Decls
{
if
d
,
ok
:=
d
.
(
*
ast
.
GenDecl
);
ok
&&
d
.
Tok
==
token
.
TYPE
{
for
_
,
s
:=
range
d
.
Specs
{
if
s
,
ok
:=
s
.
(
*
ast
.
TypeSpec
);
ok
&&
s
.
Name
.
Name
==
parts
[
0
]
{
if
s
,
ok
:=
s
.
Type
.
(
*
ast
.
StructType
);
ok
{
for
_
,
f
:=
range
s
.
Fields
.
List
{
for
_
,
name
:=
range
f
.
Names
{
if
name
.
Name
==
parts
[
1
]
{
return
f
}
}
}
}
}
}
}
}
return
nil
}
// Don't use ast.CommentGroup.Text() - we want to see exact comment text.
func
commentText
(
c
*
ast
.
CommentGroup
)
string
{
var
buf
bytes
.
Buffer
if
c
!=
nil
{
for
_
,
c
:=
range
c
.
List
{
buf
.
WriteString
(
c
.
Text
)
}
}
return
buf
.
String
()
}
func
checkFieldComments
(
t
*
testing
.
T
,
file
*
ast
.
File
,
fieldname
,
lead
,
line
string
)
{
f
:=
getField
(
file
,
fieldname
)
if
f
==
nil
{
t
.
Fatalf
(
"field not found: %s"
,
fieldname
)
}
if
got
:=
commentText
(
f
.
Doc
);
got
!=
lead
{
t
.
Errorf
(
"got lead comment %q; expected %q"
,
got
,
lead
)
}
if
got
:=
commentText
(
f
.
Comment
);
got
!=
line
{
t
.
Errorf
(
"got line comment %q; expected %q"
,
got
,
line
)
}
}
func
TestLeadAndLineComments
(
t
*
testing
.
T
)
{
f
,
err
:=
ParseFile
(
fset
,
""
,
`
package p
type T struct {
/* F1 lead comment */
//
F1 int /* F1 */ // line comment
// F2 lead
// comment
F2 int // F2 line comment
// f3 lead comment
f3 int // f3 line comment
}
`
,
ParseComments
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
checkFieldComments
(
t
,
f
,
"T.F1"
,
"/* F1 lead comment *///"
,
"/* F1 */// line comment"
)
checkFieldComments
(
t
,
f
,
"T.F2"
,
"// F2 lead// comment"
,
"// F2 line comment"
)
checkFieldComments
(
t
,
f
,
"T.f3"
,
"// f3 lead comment"
,
"// f3 line comment"
)
ast
.
FileExports
(
f
)
checkFieldComments
(
t
,
f
,
"T.F1"
,
"/* F1 lead comment *///"
,
"/* F1 */// line comment"
)
checkFieldComments
(
t
,
f
,
"T.F2"
,
"// F2 lead// comment"
,
"// F2 line comment"
)
if
getField
(
f
,
"T.f3"
)
!=
nil
{
t
.
Error
(
"not expected to find T.f3"
)
}
}
libgo/go/go/printer/nodes.go
View file @
08a680a8
...
...
@@ -60,8 +60,8 @@ func (p *printer) linebreak(line, min int, ws whiteSpace, newSection bool) (prin
// setComment sets g as the next comment if g != nil and if node comments
// are enabled - this mode is used when printing source code fragments such
// as exports only. It assumes that there
are no other pending comments to
//
interspers
e.
// as exports only. It assumes that there
is no pending comment in p.comments
//
and at most one pending comment in the p.comment cach
e.
func
(
p
*
printer
)
setComment
(
g
*
ast
.
CommentGroup
)
{
if
g
==
nil
||
!
p
.
useNodeComments
{
return
...
...
@@ -74,10 +74,19 @@ func (p *printer) setComment(g *ast.CommentGroup) {
// should never happen - handle gracefully and flush
// all comments up to g, ignore anything after that
p
.
flush
(
p
.
posFor
(
g
.
List
[
0
]
.
Pos
()),
token
.
ILLEGAL
)
p
.
comments
=
p
.
comments
[
0
:
1
]
// in debug mode, report error
p
.
internalError
(
"setComment found pending comments"
)
}
p
.
comments
[
0
]
=
g
p
.
cindex
=
0
p
.
nextComment
()
// get comment ready for use
// don't overwrite any pending comment in the p.comment cache
// (there may be a pending comment when a line comment is
// immediately followed by a lead comment with no other
// tokens inbetween)
if
p
.
commentOffset
==
infinity
{
p
.
nextComment
()
// get comment ready for use
}
}
type
exprListMode
uint
...
...
libgo/go/log/log.go
View file @
08a680a8
...
...
@@ -26,7 +26,7 @@ const (
// Bits or'ed together to control what's printed. There is no control over the
// order they appear (the order listed here) or the format they present (as
// described in the comments). A colon appears after these items:
// 2009/0123 01:23:23.123123 /a/b/c/d.go:23: message
// 2009/01
/
23 01:23:23.123123 /a/b/c/d.go:23: message
Ldate
=
1
<<
iota
// the date: 2009/01/23
Ltime
// the time: 01:23:23
Lmicroseconds
// microsecond resolution: 01:23:23.123123. assumes Ltime.
...
...
libgo/go/math/big/nat.go
View file @
08a680a8
...
...
@@ -271,10 +271,10 @@ func karatsuba(z, x, y nat) {
// xd = x1 - x0
// yd = y0 - y1
//
// z1 = xd*yd + z
1
+ z0
// = (x1-x0)*(y0 - y1) + z
1
+ z0
// = x1*y0 - x1*y1 - x0*y0 + x0*y1 + z
1
+ z0
// = x1*y0 - z
1 - z0 + x0*y1 + z1
+ z0
// z1 = xd*yd + z
2
+ z0
// = (x1-x0)*(y0 - y1) + z
2
+ z0
// = x1*y0 - x1*y1 - x0*y0 + x0*y1 + z
2
+ z0
// = x1*y0 - z
2 - z0 + x0*y1 + z2
+ z0
// = x1*y0 + x0*y1
// split x, y into "digits"
...
...
@@ -318,7 +318,7 @@ func karatsuba(z, x, y nat) {
// save original z2:z0
// (ok to use upper half of z since we're done recursing)
r
:=
z
[
n
*
4
:
]
copy
(
r
,
z
)
copy
(
r
,
z
[
:
n
*
2
]
)
// add up all partial products
//
...
...
libgo/go/math/big/nat_test.go
View file @
08a680a8
...
...
@@ -661,3 +661,21 @@ func TestExpNN(t *testing.T) {
}
}
}
func
ExpHelper
(
b
*
testing
.
B
,
x
,
y
Word
)
{
var
z
nat
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
z
.
expWW
(
x
,
y
)
}
}
func
BenchmarkExp3Power0x10
(
b
*
testing
.
B
)
{
ExpHelper
(
b
,
3
,
0x10
)
}
func
BenchmarkExp3Power0x40
(
b
*
testing
.
B
)
{
ExpHelper
(
b
,
3
,
0x40
)
}
func
BenchmarkExp3Power0x100
(
b
*
testing
.
B
)
{
ExpHelper
(
b
,
3
,
0x100
)
}
func
BenchmarkExp3Power0x400
(
b
*
testing
.
B
)
{
ExpHelper
(
b
,
3
,
0x400
)
}
func
BenchmarkExp3Power0x1000
(
b
*
testing
.
B
)
{
ExpHelper
(
b
,
3
,
0x1000
)
}
func
BenchmarkExp3Power0x4000
(
b
*
testing
.
B
)
{
ExpHelper
(
b
,
3
,
0x4000
)
}
func
BenchmarkExp3Power0x10000
(
b
*
testing
.
B
)
{
ExpHelper
(
b
,
3
,
0x10000
)
}
func
BenchmarkExp3Power0x40000
(
b
*
testing
.
B
)
{
ExpHelper
(
b
,
3
,
0x40000
)
}
func
BenchmarkExp3Power0x100000
(
b
*
testing
.
B
)
{
ExpHelper
(
b
,
3
,
0x100000
)
}
func
BenchmarkExp3Power0x400000
(
b
*
testing
.
B
)
{
ExpHelper
(
b
,
3
,
0x400000
)
}
libgo/go/mime/multipart/multipart.go
View file @
08a680a8
...
...
@@ -22,11 +22,6 @@ import (
"net/textproto"
)
// TODO(bradfitz): inline these once the compiler can inline them in
// read-only situation (such as bytes.HasSuffix)
var
lf
=
[]
byte
(
"
\n
"
)
var
crlf
=
[]
byte
(
"
\r\n
"
)
var
emptyParams
=
make
(
map
[
string
]
string
)
// A Part represents a single part in a multipart body.
...
...
@@ -36,8 +31,9 @@ type Part struct {
// i.e. "foo-bar" changes case to "Foo-Bar"
Header
textproto
.
MIMEHeader
buffer
*
bytes
.
Buffer
mr
*
Reader
buffer
*
bytes
.
Buffer
mr
*
Reader
bytesRead
int
disposition
string
dispositionParams
map
[
string
]
string
...
...
@@ -113,14 +109,26 @@ func (bp *Part) populateHeaders() error {
// Read reads the body of a part, after its headers and before the
// next part (if any) begins.
func
(
p
*
Part
)
Read
(
d
[]
byte
)
(
n
int
,
err
error
)
{
defer
func
()
{
p
.
bytesRead
+=
n
}()
if
p
.
buffer
.
Len
()
>=
len
(
d
)
{
// Internal buffer of unconsumed data is large enough for
// the read request. No need to parse more at the moment.
return
p
.
buffer
.
Read
(
d
)
}
peek
,
err
:=
p
.
mr
.
bufReader
.
Peek
(
4096
)
// TODO(bradfitz): add buffer size accessor
unexpectedEof
:=
err
==
io
.
EOF
if
err
!=
nil
&&
!
unexpectedEof
{
// Look for an immediate empty part without a leading \r\n
// before the boundary separator. Some MIME code makes empty
// parts like this. Most browsers, however, write the \r\n
// before the subsequent boundary even for empty parts and
// won't hit this path.
if
p
.
bytesRead
==
0
&&
p
.
mr
.
peekBufferIsEmptyPart
(
peek
)
{
return
0
,
io
.
EOF
}
unexpectedEOF
:=
err
==
io
.
EOF
if
err
!=
nil
&&
!
unexpectedEOF
{
return
0
,
fmt
.
Errorf
(
"multipart: Part Read: %v"
,
err
)
}
if
peek
==
nil
{
...
...
@@ -138,7 +146,7 @@ func (p *Part) Read(d []byte) (n int, err error) {
foundBoundary
=
true
}
else
if
safeCount
:=
len
(
peek
)
-
len
(
p
.
mr
.
nlDashBoundary
);
safeCount
>
0
{
nCopy
=
safeCount
}
else
if
unexpectedE
of
{
}
else
if
unexpectedE
OF
{
// If we've run out of peek buffer and the boundary
// wasn't found (and can't possibly fit), we must have
// hit the end of the file unexpectedly.
...
...
@@ -172,7 +180,10 @@ type Reader struct {
currentPart
*
Part
partsRead
int
nl
,
nlDashBoundary
,
dashBoundaryDash
,
dashBoundary
[]
byte
nl
[]
byte
// "\r\n" or "\n" (set after seeing first boundary line)
nlDashBoundary
[]
byte
// nl + "--boundary"
dashBoundaryDash
[]
byte
// "--boundary--"
dashBoundary
[]
byte
// "--boundary"
}
// NextPart returns the next part in the multipart or an error.
...
...
@@ -185,7 +196,7 @@ func (r *Reader) NextPart() (*Part, error) {
expectNewPart
:=
false
for
{
line
,
err
:=
r
.
bufReader
.
ReadSlice
(
'\n'
)
if
err
==
io
.
EOF
&&
bytes
.
Equal
(
line
,
r
.
dashBoundaryDash
)
{
if
err
==
io
.
EOF
&&
r
.
isFinalBoundary
(
line
)
{
// If the buffer ends in "--boundary--" without the
// trailing "\r\n", ReadSlice will return an error
// (since it's missing the '\n'), but this is a valid
...
...
@@ -207,7 +218,7 @@ func (r *Reader) NextPart() (*Part, error) {
return
bp
,
nil
}
if
hasPrefixThenNewline
(
line
,
r
.
dashBoundaryDash
)
{
if
r
.
isFinalBoundary
(
line
)
{
// Expected EOF
return
nil
,
io
.
EOF
}
...
...
@@ -235,7 +246,19 @@ func (r *Reader) NextPart() (*Part, error) {
panic
(
"unreachable"
)
}
func
(
mr
*
Reader
)
isBoundaryDelimiterLine
(
line
[]
byte
)
bool
{
// isFinalBoundary returns whether line is the final boundary line
// indiciating that all parts are over.
// It matches `^--boundary--[ \t]*(\r\n)?$`
func
(
mr
*
Reader
)
isFinalBoundary
(
line
[]
byte
)
bool
{
if
!
bytes
.
HasPrefix
(
line
,
mr
.
dashBoundaryDash
)
{
return
false
}
rest
:=
line
[
len
(
mr
.
dashBoundaryDash
)
:
]
rest
=
skipLWSPChar
(
rest
)
return
len
(
rest
)
==
0
||
bytes
.
Equal
(
rest
,
mr
.
nl
)
}
func
(
mr
*
Reader
)
isBoundaryDelimiterLine
(
line
[]
byte
)
(
ret
bool
)
{
// http://tools.ietf.org/html/rfc2046#section-5.1
// The boundary delimiter line is then defined as a line
// consisting entirely of two hyphen characters ("-",
...
...
@@ -245,32 +268,52 @@ func (mr *Reader) isBoundaryDelimiterLine(line []byte) bool {
if
!
bytes
.
HasPrefix
(
line
,
mr
.
dashBoundary
)
{
return
false
}
if
bytes
.
HasSuffix
(
line
,
mr
.
nl
)
{
return
onlyHorizontalWhitespace
(
line
[
len
(
mr
.
dashBoundary
)
:
len
(
line
)
-
len
(
mr
.
nl
)])
rest
:=
line
[
len
(
mr
.
dashBoundary
)
:
]
rest
=
skipLWSPChar
(
rest
)
// On the first part, see our lines are ending in \n instead of \r\n
// and switch into that mode if so. This is a violation of the spec,
// but occurs in practice.
if
mr
.
partsRead
==
0
&&
len
(
rest
)
==
1
&&
rest
[
0
]
==
'\n'
{
mr
.
nl
=
mr
.
nl
[
1
:
]
mr
.
nlDashBoundary
=
mr
.
nlDashBoundary
[
1
:
]
}
// Violate the spec and also support newlines without the
// carriage return...
if
mr
.
partsRead
==
0
&&
bytes
.
HasSuffix
(
line
,
lf
)
{
if
onlyHorizontalWhitespace
(
line
[
len
(
mr
.
dashBoundary
)
:
len
(
line
)
-
1
])
{
mr
.
nl
=
mr
.
nl
[
1
:
]
mr
.
nlDashBoundary
=
mr
.
nlDashBoundary
[
1
:
]
return
true
}
}
return
false
return
bytes
.
Equal
(
rest
,
mr
.
nl
)
}
func
onlyHorizontalWhitespace
(
s
[]
byte
)
bool
{
for
_
,
b
:=
range
s
{
if
b
!=
' '
&&
b
!=
'\t'
{
return
false
}
// peekBufferIsEmptyPart returns whether the provided peek-ahead
// buffer represents an empty part. This is only called if we've not
// already read any bytes in this part and checks for the case of MIME
// software not writing the \r\n on empty parts. Some does, some
// doesn't.
//
// This checks that what follows the "--boundary" is actually the end
// ("--boundary--" with optional whitespace) or optional whitespace
// and then a newline, so we don't catch "--boundaryFAKE", in which
// case the whole line is part of the data.
func
(
mr
*
Reader
)
peekBufferIsEmptyPart
(
peek
[]
byte
)
bool
{
// End of parts case.
// Test whether peek matches `^--boundary--[ \t]*(?:\r\n|$)`
if
bytes
.
HasPrefix
(
peek
,
mr
.
dashBoundaryDash
)
{
rest
:=
peek
[
len
(
mr
.
dashBoundaryDash
)
:
]
rest
=
skipLWSPChar
(
rest
)
return
bytes
.
HasPrefix
(
rest
,
mr
.
nl
)
||
len
(
rest
)
==
0
}
return
true
if
!
bytes
.
HasPrefix
(
peek
,
mr
.
dashBoundary
)
{
return
false
}
// Test whether rest matches `^[ \t]*\r\n`)
rest
:=
peek
[
len
(
mr
.
dashBoundary
)
:
]
rest
=
skipLWSPChar
(
rest
)
return
bytes
.
HasPrefix
(
rest
,
mr
.
nl
)
}
func
hasPrefixThenNewline
(
s
,
prefix
[]
byte
)
bool
{
return
bytes
.
HasPrefix
(
s
,
prefix
)
&&
(
len
(
s
)
==
len
(
prefix
)
+
1
&&
s
[
len
(
s
)
-
1
]
==
'\n'
||
len
(
s
)
==
len
(
prefix
)
+
2
&&
bytes
.
HasSuffix
(
s
,
crlf
))
// skipLWSPChar returns b with leading spaces and tabs removed.
// RFC 822 defines:
// LWSP-char = SPACE / HTAB
func
skipLWSPChar
(
b
[]
byte
)
[]
byte
{
for
len
(
b
)
>
0
&&
(
b
[
0
]
==
' '
||
b
[
0
]
==
'\t'
)
{
b
=
b
[
1
:
]
}
return
b
}
libgo/go/mime/multipart/multipart_test.go
View file @
08a680a8
...
...
@@ -10,20 +10,13 @@ import (
"fmt"
"io"
"io/ioutil"
"net/textproto"
"os"
"reflect"
"strings"
"testing"
)
func
TestHorizontalWhitespace
(
t
*
testing
.
T
)
{
if
!
onlyHorizontalWhitespace
([]
byte
(
"
\t
"
))
{
t
.
Error
(
"expected pass"
)
}
if
onlyHorizontalWhitespace
([]
byte
(
"foo bar"
))
{
t
.
Error
(
"expected failure"
)
}
}
func
TestBoundaryLine
(
t
*
testing
.
T
)
{
mr
:=
NewReader
(
strings
.
NewReader
(
""
),
"myBoundary"
)
if
!
mr
.
isBoundaryDelimiterLine
([]
byte
(
"--myBoundary
\r\n
"
))
{
...
...
@@ -319,29 +312,6 @@ Oh no, premature EOF!
}
}
func
TestZeroLengthBody
(
t
*
testing
.
T
)
{
testBody
:=
strings
.
Replace
(
`
This is a multi-part message. This line is ignored.
--MyBoundary
foo: bar
--MyBoundary--
`
,
"
\n
"
,
"
\r\n
"
,
-
1
)
r
:=
NewReader
(
strings
.
NewReader
(
testBody
),
"MyBoundary"
)
part
,
err
:=
r
.
NextPart
()
if
err
!=
nil
{
t
.
Fatalf
(
"didn't get a part"
)
}
n
,
err
:=
io
.
Copy
(
ioutil
.
Discard
,
part
)
if
err
!=
nil
{
t
.
Errorf
(
"error reading part: %v"
,
err
)
}
if
n
!=
0
{
t
.
Errorf
(
"read %d bytes; expected 0"
,
n
)
}
}
type
slowReader
struct
{
r
io
.
Reader
}
...
...
@@ -427,3 +397,214 @@ func TestNested(t *testing.T) {
t
.
Fatalf
(
"final outer NextPart = %v; want io.EOF"
,
err
)
}
}
type
headerBody
struct
{
header
textproto
.
MIMEHeader
body
string
}
func
formData
(
key
,
value
string
)
headerBody
{
return
headerBody
{
textproto
.
MIMEHeader
{
"Content-Type"
:
{
"text/plain; charset=ISO-8859-1"
},
"Content-Disposition"
:
{
"form-data; name="
+
key
},
},
value
,
}
}
type
parseTest
struct
{
name
string
in
,
sep
string
want
[]
headerBody
}
var
parseTests
=
[]
parseTest
{
// Actual body from App Engine on a blob upload. The final part (the
// Content-Type: message/external-body) is what App Engine replaces
// the uploaded file with. The other form fields (prefixed with
// "other" in their form-data name) are unchanged. A bug was
// reported with blob uploads failing when the other fields were
// empty. This was the MIME POST body that previously failed.
{
name
:
"App Engine post"
,
sep
:
"00151757727e9583fd04bfbca4c6"
,
in
:
"--00151757727e9583fd04bfbca4c6
\r\n
Content-Type: text/plain; charset=ISO-8859-1
\r\n
Content-Disposition: form-data; name=otherEmpty1
\r\n\r\n
--00151757727e9583fd04bfbca4c6
\r\n
Content-Type: text/plain; charset=ISO-8859-1
\r\n
Content-Disposition: form-data; name=otherFoo1
\r\n\r\n
foo
\r\n
--00151757727e9583fd04bfbca4c6
\r\n
Content-Type: text/plain; charset=ISO-8859-1
\r\n
Content-Disposition: form-data; name=otherFoo2
\r\n\r\n
foo
\r\n
--00151757727e9583fd04bfbca4c6
\r\n
Content-Type: text/plain; charset=ISO-8859-1
\r\n
Content-Disposition: form-data; name=otherEmpty2
\r\n\r\n
--00151757727e9583fd04bfbca4c6
\r\n
Content-Type: text/plain; charset=ISO-8859-1
\r\n
Content-Disposition: form-data; name=otherRepeatFoo
\r\n\r\n
foo
\r\n
--00151757727e9583fd04bfbca4c6
\r\n
Content-Type: text/plain; charset=ISO-8859-1
\r\n
Content-Disposition: form-data; name=otherRepeatFoo
\r\n\r\n
foo
\r\n
--00151757727e9583fd04bfbca4c6
\r\n
Content-Type: text/plain; charset=ISO-8859-1
\r\n
Content-Disposition: form-data; name=otherRepeatEmpty
\r\n\r\n
--00151757727e9583fd04bfbca4c6
\r\n
Content-Type: text/plain; charset=ISO-8859-1
\r\n
Content-Disposition: form-data; name=otherRepeatEmpty
\r\n\r\n
--00151757727e9583fd04bfbca4c6
\r\n
Content-Type: text/plain; charset=ISO-8859-1
\r\n
Content-Disposition: form-data; name=submit
\r\n\r\n
Submit
\r\n
--00151757727e9583fd04bfbca4c6
\r\n
Content-Type: message/external-body; charset=ISO-8859-1; blob-key=AHAZQqG84qllx7HUqO_oou5EvdYQNS3Mbbkb0RjjBoM_Kc1UqEN2ygDxWiyCPulIhpHRPx-VbpB6RX4MrsqhWAi_ZxJ48O9P2cTIACbvATHvg7IgbvZytyGMpL7xO1tlIvgwcM47JNfv_tGhy1XwyEUO8oldjPqg5Q
\r\n
Content-Disposition: form-data; name=file; filename=
\"
fall.png
\"\r\n\r\n
Content-Type: image/png
\r\n
Content-Length: 232303
\r\n
X-AppEngine-Upload-Creation: 2012-05-10 23:14:02.715173
\r\n
Content-MD5: MzRjODU1ZDZhZGU1NmRlOWEwZmMwMDdlODBmZTA0NzA=
\r\n
Content-Disposition: form-data; name=file; filename=
\"
fall.png
\"\r\n\r\n\r\n
--00151757727e9583fd04bfbca4c6--"
,
want
:
[]
headerBody
{
formData
(
"otherEmpty1"
,
""
),
formData
(
"otherFoo1"
,
"foo"
),
formData
(
"otherFoo2"
,
"foo"
),
formData
(
"otherEmpty2"
,
""
),
formData
(
"otherRepeatFoo"
,
"foo"
),
formData
(
"otherRepeatFoo"
,
"foo"
),
formData
(
"otherRepeatEmpty"
,
""
),
formData
(
"otherRepeatEmpty"
,
""
),
formData
(
"submit"
,
"Submit"
),
{
textproto
.
MIMEHeader
{
"Content-Type"
:
{
"message/external-body; charset=ISO-8859-1; blob-key=AHAZQqG84qllx7HUqO_oou5EvdYQNS3Mbbkb0RjjBoM_Kc1UqEN2ygDxWiyCPulIhpHRPx-VbpB6RX4MrsqhWAi_ZxJ48O9P2cTIACbvATHvg7IgbvZytyGMpL7xO1tlIvgwcM47JNfv_tGhy1XwyEUO8oldjPqg5Q"
},
"Content-Disposition"
:
{
"form-data; name=file; filename=
\"
fall.png
\"
"
},
},
"Content-Type: image/png
\r\n
Content-Length: 232303
\r\n
X-AppEngine-Upload-Creation: 2012-05-10 23:14:02.715173
\r\n
Content-MD5: MzRjODU1ZDZhZGU1NmRlOWEwZmMwMDdlODBmZTA0NzA=
\r\n
Content-Disposition: form-data; name=file; filename=
\"
fall.png
\"\r\n\r\n
"
},
},
},
// Single empty part, ended with --boundary immediately after headers.
{
name
:
"single empty part, --boundary"
,
sep
:
"abc"
,
in
:
"--abc
\r\n
Foo: bar
\r\n\r\n
--abc--"
,
want
:
[]
headerBody
{
{
textproto
.
MIMEHeader
{
"Foo"
:
{
"bar"
}},
""
},
},
},
// Single empty part, ended with \r\n--boundary immediately after headers.
{
name
:
"single empty part,
\r\n
--boundary"
,
sep
:
"abc"
,
in
:
"--abc
\r\n
Foo: bar
\r\n\r\n\r\n
--abc--"
,
want
:
[]
headerBody
{
{
textproto
.
MIMEHeader
{
"Foo"
:
{
"bar"
}},
""
},
},
},
// Final part empty.
{
name
:
"final part empty"
,
sep
:
"abc"
,
in
:
"--abc
\r\n
Foo: bar
\r\n\r\n
--abc
\r\n
Foo2: bar2
\r\n\r\n
--abc--"
,
want
:
[]
headerBody
{
{
textproto
.
MIMEHeader
{
"Foo"
:
{
"bar"
}},
""
},
{
textproto
.
MIMEHeader
{
"Foo2"
:
{
"bar2"
}},
""
},
},
},
// Final part empty with newlines after final separator.
{
name
:
"final part empty then crlf"
,
sep
:
"abc"
,
in
:
"--abc
\r\n
Foo: bar
\r\n\r\n
--abc--
\r\n
"
,
want
:
[]
headerBody
{
{
textproto
.
MIMEHeader
{
"Foo"
:
{
"bar"
}},
""
},
},
},
// Final part empty with lwsp-chars after final separator.
{
name
:
"final part empty then lwsp"
,
sep
:
"abc"
,
in
:
"--abc
\r\n
Foo: bar
\r\n\r\n
--abc--
\t
"
,
want
:
[]
headerBody
{
{
textproto
.
MIMEHeader
{
"Foo"
:
{
"bar"
}},
""
},
},
},
// No parts (empty form as submitted by Chrome)
{
name
:
"no parts"
,
sep
:
"----WebKitFormBoundaryQfEAfzFOiSemeHfA"
,
in
:
"------WebKitFormBoundaryQfEAfzFOiSemeHfA--
\r\n
"
,
want
:
[]
headerBody
{},
},
// Part containing data starting with the boundary, but with additional suffix.
{
name
:
"fake separator as data"
,
sep
:
"sep"
,
in
:
"--sep
\r\n
Foo: bar
\r\n\r\n
--sepFAKE
\r\n
--sep--"
,
want
:
[]
headerBody
{
{
textproto
.
MIMEHeader
{
"Foo"
:
{
"bar"
}},
"--sepFAKE"
},
},
},
// Part containing a boundary with whitespace following it.
{
name
:
"boundary with whitespace"
,
sep
:
"sep"
,
in
:
"--sep
\r\n
Foo: bar
\r\n\r\n
text
\r\n
--sep--"
,
want
:
[]
headerBody
{
{
textproto
.
MIMEHeader
{
"Foo"
:
{
"bar"
}},
"text"
},
},
},
// With ignored leading line.
{
name
:
"leading line"
,
sep
:
"MyBoundary"
,
in
:
strings
.
Replace
(
`This is a multi-part message. This line is ignored.
--MyBoundary
foo: bar
--MyBoundary--`
,
"
\n
"
,
"
\r\n
"
,
-
1
),
want
:
[]
headerBody
{
{
textproto
.
MIMEHeader
{
"Foo"
:
{
"bar"
}},
""
},
},
},
roundTripParseTest
(),
}
func
TestParse
(
t
*
testing
.
T
)
{
Cases
:
for
_
,
tt
:=
range
parseTests
{
r
:=
NewReader
(
strings
.
NewReader
(
tt
.
in
),
tt
.
sep
)
got
:=
[]
headerBody
{}
for
{
p
,
err
:=
r
.
NextPart
()
if
err
==
io
.
EOF
{
break
}
if
err
!=
nil
{
t
.
Errorf
(
"in test %q, NextPart: %v"
,
tt
.
name
,
err
)
continue
Cases
}
pbody
,
err
:=
ioutil
.
ReadAll
(
p
)
if
err
!=
nil
{
t
.
Errorf
(
"in test %q, error reading part: %v"
,
tt
.
name
,
err
)
continue
Cases
}
got
=
append
(
got
,
headerBody
{
p
.
Header
,
string
(
pbody
)})
}
if
!
reflect
.
DeepEqual
(
tt
.
want
,
got
)
{
t
.
Errorf
(
"test %q:
\n
got: %v
\n
want: %v"
,
tt
.
name
,
got
,
tt
.
want
)
if
len
(
tt
.
want
)
!=
len
(
got
)
{
t
.
Errorf
(
"test %q: got %d parts, want %d"
,
tt
.
name
,
len
(
got
),
len
(
tt
.
want
))
}
else
if
len
(
got
)
>
1
{
for
pi
,
wantPart
:=
range
tt
.
want
{
if
!
reflect
.
DeepEqual
(
wantPart
,
got
[
pi
])
{
t
.
Errorf
(
"test %q, part %d:
\n
got: %v
\n
want: %v"
,
tt
.
name
,
pi
,
got
[
pi
],
wantPart
)
}
}
}
}
}
}
func
roundTripParseTest
()
parseTest
{
t
:=
parseTest
{
name
:
"round trip"
,
want
:
[]
headerBody
{
formData
(
"empty"
,
""
),
formData
(
"lf"
,
"
\n
"
),
formData
(
"cr"
,
"
\r
"
),
formData
(
"crlf"
,
"
\r\n
"
),
formData
(
"foo"
,
"bar"
),
},
}
var
buf
bytes
.
Buffer
w
:=
NewWriter
(
&
buf
)
for
_
,
p
:=
range
t
.
want
{
pw
,
err
:=
w
.
CreatePart
(
p
.
header
)
if
err
!=
nil
{
panic
(
err
)
}
_
,
err
=
pw
.
Write
([]
byte
(
p
.
body
))
if
err
!=
nil
{
panic
(
err
)
}
}
w
.
Close
()
t
.
in
=
buf
.
String
()
t
.
sep
=
w
.
Boundary
()
return
t
}
libgo/go/net/file.go
View file @
08a680a8
...
...
@@ -89,8 +89,8 @@ func FileConn(f *os.File) (c Conn, err error) {
// FileListener returns a copy of the network listener corresponding
// to the open file f. It is the caller's responsibility to close l
// when finished. Closing
c does not affect l, and closing l
does not
// affect
c
.
// when finished. Closing
l does not affect f, and closing f
does not
// affect
l
.
func
FileListener
(
f
*
os
.
File
)
(
l
Listener
,
err
error
)
{
fd
,
err
:=
newFileFD
(
f
)
if
err
!=
nil
{
...
...
libgo/go/net/http/client.go
View file @
08a680a8
...
...
@@ -278,6 +278,11 @@ func (c *Client) Post(url string, bodyType string, body io.Reader) (r *Response,
return
nil
,
err
}
req
.
Header
.
Set
(
"Content-Type"
,
bodyType
)
if
c
.
Jar
!=
nil
{
for
_
,
cookie
:=
range
c
.
Jar
.
Cookies
(
req
.
URL
)
{
req
.
AddCookie
(
cookie
)
}
}
r
,
err
=
send
(
req
,
c
.
Transport
)
if
err
==
nil
&&
c
.
Jar
!=
nil
{
c
.
Jar
.
SetCookies
(
req
.
URL
,
r
.
Cookies
())
...
...
libgo/go/net/http/client_test.go
View file @
08a680a8
...
...
@@ -256,6 +256,31 @@ var echoCookiesRedirectHandler = HandlerFunc(func(w ResponseWriter, r *Request)
}
})
func
TestClientSendsCookieFromJar
(
t
*
testing
.
T
)
{
tr
:=
&
recordingTransport
{}
client
:=
&
Client
{
Transport
:
tr
}
client
.
Jar
=
&
TestJar
{
perURL
:
make
(
map
[
string
][]
*
Cookie
)}
us
:=
"http://dummy.faketld/"
u
,
_
:=
url
.
Parse
(
us
)
client
.
Jar
.
SetCookies
(
u
,
expectedCookies
)
client
.
Get
(
us
)
// Note: doesn't hit network
matchReturnedCookies
(
t
,
expectedCookies
,
tr
.
req
.
Cookies
())
client
.
Head
(
us
)
// Note: doesn't hit network
matchReturnedCookies
(
t
,
expectedCookies
,
tr
.
req
.
Cookies
())
client
.
Post
(
us
,
"text/plain"
,
strings
.
NewReader
(
"body"
))
// Note: doesn't hit network
matchReturnedCookies
(
t
,
expectedCookies
,
tr
.
req
.
Cookies
())
client
.
PostForm
(
us
,
url
.
Values
{})
// Note: doesn't hit network
matchReturnedCookies
(
t
,
expectedCookies
,
tr
.
req
.
Cookies
())
req
,
_
:=
NewRequest
(
"GET"
,
us
,
nil
)
client
.
Do
(
req
)
// Note: doesn't hit network
matchReturnedCookies
(
t
,
expectedCookies
,
tr
.
req
.
Cookies
())
}
// Just enough correctness for our redirect tests. Uses the URL.Host as the
// scope of all cookies.
type
TestJar
struct
{
...
...
libgo/go/net/http/proxy_test.go
View file @
08a680a8
...
...
@@ -5,6 +5,7 @@
package
http
import
(
"net/url"
"os"
"testing"
)
...
...
@@ -46,3 +47,32 @@ func TestUseProxy(t *testing.T) {
}
}
}
var
cacheKeysTests
=
[]
struct
{
proxy
string
scheme
string
addr
string
key
string
}{
{
""
,
"http"
,
"foo.com"
,
"|http|foo.com"
},
{
""
,
"https"
,
"foo.com"
,
"|https|foo.com"
},
{
"http://foo.com"
,
"http"
,
"foo.com"
,
"http://foo.com|http|"
},
{
"http://foo.com"
,
"https"
,
"foo.com"
,
"http://foo.com|https|foo.com"
},
}
func
TestCacheKeys
(
t
*
testing
.
T
)
{
for
_
,
tt
:=
range
cacheKeysTests
{
var
proxy
*
url
.
URL
if
tt
.
proxy
!=
""
{
u
,
err
:=
url
.
Parse
(
tt
.
proxy
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
proxy
=
u
}
cm
:=
connectMethod
{
proxy
,
tt
.
scheme
,
tt
.
addr
}
if
cm
.
String
()
!=
tt
.
key
{
t
.
Fatalf
(
"{%q, %q, %q} cache key %q; want %q"
,
tt
.
proxy
,
tt
.
scheme
,
tt
.
addr
,
cm
.
String
(),
tt
.
key
)
}
}
}
libgo/go/net/http/response.go
View file @
08a680a8
...
...
@@ -202,9 +202,12 @@ func (r *Response) Write(w io.Writer) error {
text
=
"status code "
+
strconv
.
Itoa
(
r
.
StatusCode
)
}
}
io
.
WriteString
(
w
,
"HTTP/"
+
strconv
.
Itoa
(
r
.
ProtoMajor
)
+
"."
)
io
.
WriteString
(
w
,
strconv
.
Itoa
(
r
.
ProtoMinor
)
+
" "
)
io
.
WriteString
(
w
,
strconv
.
Itoa
(
r
.
StatusCode
)
+
" "
+
text
+
"
\r\n
"
)
protoMajor
,
protoMinor
:=
strconv
.
Itoa
(
r
.
ProtoMajor
),
strconv
.
Itoa
(
r
.
ProtoMinor
)
statusCode
:=
strconv
.
Itoa
(
r
.
StatusCode
)
+
" "
if
strings
.
HasPrefix
(
text
,
statusCode
)
{
text
=
text
[
len
(
statusCode
)
:
]
}
io
.
WriteString
(
w
,
"HTTP/"
+
protoMajor
+
"."
+
protoMinor
+
" "
+
statusCode
+
text
+
"
\r\n
"
)
// Process Body,ContentLength,Close,Trailer
tw
,
err
:=
newTransferWriter
(
r
)
...
...
libgo/go/net/http/response_test.go
View file @
08a680a8
...
...
@@ -14,6 +14,7 @@ import (
"io/ioutil"
"net/url"
"reflect"
"strings"
"testing"
)
...
...
@@ -444,3 +445,17 @@ func TestLocationResponse(t *testing.T) {
}
}
}
func
TestResponseStatusStutter
(
t
*
testing
.
T
)
{
r
:=
&
Response
{
Status
:
"123 some status"
,
StatusCode
:
123
,
ProtoMajor
:
1
,
ProtoMinor
:
3
,
}
var
buf
bytes
.
Buffer
r
.
Write
(
&
buf
)
if
strings
.
Contains
(
buf
.
String
(),
"123 123"
)
{
t
.
Errorf
(
"stutter in status: %s"
,
buf
.
String
())
}
}
libgo/go/net/http/server.go
View file @
08a680a8
...
...
@@ -31,7 +31,7 @@ import (
// Errors introduced by the HTTP server.
var
(
ErrWriteAfterFlush
=
errors
.
New
(
"Conn.Write called after Flush"
)
ErrBodyNotAllowed
=
errors
.
New
(
"http: response status code does not allow body"
)
ErrBodyNotAllowed
=
errors
.
New
(
"http: re
quest method or re
sponse status code does not allow body"
)
ErrHijacked
=
errors
.
New
(
"Conn has been hijacked"
)
ErrContentLength
=
errors
.
New
(
"Conn.Write wrote more than the declared Content-Length"
)
)
...
...
libgo/go/net/http/transfer.go
View file @
08a680a8
...
...
@@ -71,7 +71,9 @@ func newTransferWriter(r interface{}) (t *transferWriter, err error) {
}
}
case
*
Response
:
t
.
Method
=
rr
.
Request
.
Method
if
rr
.
Request
!=
nil
{
t
.
Method
=
rr
.
Request
.
Method
}
t
.
Body
=
rr
.
Body
t
.
BodyCloser
=
rr
.
Body
t
.
ContentLength
=
rr
.
ContentLength
...
...
@@ -79,7 +81,7 @@ func newTransferWriter(r interface{}) (t *transferWriter, err error) {
t
.
TransferEncoding
=
rr
.
TransferEncoding
t
.
Trailer
=
rr
.
Trailer
atLeastHTTP11
=
rr
.
ProtoAtLeast
(
1
,
1
)
t
.
ResponseToHEAD
=
noBodyExpected
(
rr
.
Reques
t
.
Method
)
t
.
ResponseToHEAD
=
noBodyExpected
(
t
.
Method
)
}
// Sanitize Body,ContentLength,TransferEncoding
...
...
libgo/go/net/http/transport.go
View file @
08a680a8
...
...
@@ -450,10 +450,14 @@ type connectMethod struct {
func
(
ck
*
connectMethod
)
String
()
string
{
proxyStr
:=
""
targetAddr
:=
ck
.
targetAddr
if
ck
.
proxyURL
!=
nil
{
proxyStr
=
ck
.
proxyURL
.
String
()
if
ck
.
targetScheme
==
"http"
{
targetAddr
=
""
}
}
return
strings
.
Join
([]
string
{
proxyStr
,
ck
.
targetScheme
,
ck
.
targetAddr
},
"|"
)
return
strings
.
Join
([]
string
{
proxyStr
,
ck
.
targetScheme
,
targetAddr
},
"|"
)
}
// addr returns the first hop "host:port" to which we need to TCP connect.
...
...
libgo/go/net/mail/message.go
View file @
08a680a8
...
...
@@ -69,11 +69,12 @@ var dateLayouts []string
func
init
()
{
// Generate layouts based on RFC 5322, section 3.3.
dows
:=
[
...
]
string
{
""
,
"Mon, "
}
// day-of-week
days
:=
[
...
]
string
{
"2"
,
"02"
}
// day = 1*2DIGIT
years
:=
[
...
]
string
{
"2006"
,
"06"
}
// year = 4*DIGIT / 2*DIGIT
seconds
:=
[
...
]
string
{
":05"
,
""
}
// second
zones
:=
[
...
]
string
{
"-0700"
,
"MST"
}
// zone = (("+" / "-") 4DIGIT) / "GMT" / ...
dows
:=
[
...
]
string
{
""
,
"Mon, "
}
// day-of-week
days
:=
[
...
]
string
{
"2"
,
"02"
}
// day = 1*2DIGIT
years
:=
[
...
]
string
{
"2006"
,
"06"
}
// year = 4*DIGIT / 2*DIGIT
seconds
:=
[
...
]
string
{
":05"
,
""
}
// second
// "-0700 (MST)" is not in RFC 5322, but is common.
zones
:=
[
...
]
string
{
"-0700"
,
"MST"
,
"-0700 (MST)"
}
// zone = (("+" / "-") 4DIGIT) / "GMT" / ...
for
_
,
dow
:=
range
dows
{
for
_
,
day
:=
range
days
{
...
...
libgo/go/net/mail/message_test.go
View file @
08a680a8
...
...
@@ -95,6 +95,11 @@ func TestDateParsing(t *testing.T) {
"21 Nov 97 09:55:06 GMT"
,
time
.
Date
(
1997
,
11
,
21
,
9
,
55
,
6
,
0
,
time
.
FixedZone
(
"GMT"
,
0
)),
},
// Commonly found format not specified by RFC 5322.
{
"Fri, 21 Nov 1997 09:55:06 -0600 (MDT)"
,
time
.
Date
(
1997
,
11
,
21
,
9
,
55
,
6
,
0
,
time
.
FixedZone
(
""
,
-
6
*
60
*
60
)),
},
}
for
_
,
test
:=
range
tests
{
hdr
:=
Header
{
...
...
libgo/go/net/url/url.go
View file @
08a680a8
...
...
@@ -401,11 +401,12 @@ Error:
}
func
parseAuthority
(
authority
string
)
(
user
*
Userinfo
,
host
string
,
err
error
)
{
if
strings
.
Index
(
authority
,
"@"
)
<
0
{
i
:=
strings
.
LastIndex
(
authority
,
"@"
)
if
i
<
0
{
host
=
authority
return
}
userinfo
,
host
:=
split
(
authority
,
'@'
,
true
)
userinfo
,
host
:=
authority
[
:
i
],
authority
[
i
+
1
:
]
if
strings
.
Index
(
userinfo
,
":"
)
<
0
{
if
userinfo
,
err
=
unescape
(
userinfo
,
encodeUserPassword
);
err
!=
nil
{
return
...
...
libgo/go/net/url/url_test.go
View file @
08a680a8
...
...
@@ -188,6 +188,37 @@ var urltests = []URLTest{
},
"http://user:password@google.com"
,
},
// unescaped @ in username should not confuse host
{
"http://j@ne:password@google.com"
,
&
URL
{
Scheme
:
"http"
,
User
:
UserPassword
(
"j@ne"
,
"password"
),
Host
:
"google.com"
,
},
"http://j%40ne:password@google.com"
,
},
// unescaped @ in password should not confuse host
{
"http://jane:p@ssword@google.com"
,
&
URL
{
Scheme
:
"http"
,
User
:
UserPassword
(
"jane"
,
"p@ssword"
),
Host
:
"google.com"
,
},
"http://jane:p%40ssword@google.com"
,
},
{
"http://j@ne:password@google.com/p@th?q=@go"
,
&
URL
{
Scheme
:
"http"
,
User
:
UserPassword
(
"j@ne"
,
"password"
),
Host
:
"google.com"
,
Path
:
"/p@th"
,
RawQuery
:
"q=@go"
,
},
"http://j%40ne:password@google.com/p@th?q=@go"
,
},
{
"http://www.google.com/?q=go+language#foo"
,
&
URL
{
...
...
libgo/go/os/exec/exec.go
View file @
08a680a8
...
...
@@ -204,6 +204,12 @@ func (c *Cmd) writerDescriptor(w io.Writer) (f *os.File, err error) {
return
pw
,
nil
}
func
(
c
*
Cmd
)
closeDescriptors
(
closers
[]
io
.
Closer
)
{
for
_
,
fd
:=
range
closers
{
fd
.
Close
()
}
}
// Run starts the specified command and waits for it to complete.
//
// The returned error is nil if the command runs, has no problems
...
...
@@ -233,6 +239,8 @@ func (c *Cmd) Start() error {
for
_
,
setupFd
:=
range
[]
F
{(
*
Cmd
)
.
stdin
,
(
*
Cmd
)
.
stdout
,
(
*
Cmd
)
.
stderr
}
{
fd
,
err
:=
setupFd
(
c
)
if
err
!=
nil
{
c
.
closeDescriptors
(
c
.
closeAfterStart
)
c
.
closeDescriptors
(
c
.
closeAfterWait
)
return
err
}
c
.
childFiles
=
append
(
c
.
childFiles
,
fd
)
...
...
@@ -247,12 +255,12 @@ func (c *Cmd) Start() error {
Sys
:
c
.
SysProcAttr
,
})
if
err
!=
nil
{
c
.
closeDescriptors
(
c
.
closeAfterStart
)
c
.
closeDescriptors
(
c
.
closeAfterWait
)
return
err
}
for
_
,
fd
:=
range
c
.
closeAfterStart
{
fd
.
Close
()
}
c
.
closeDescriptors
(
c
.
closeAfterStart
)
c
.
errch
=
make
(
chan
error
,
len
(
c
.
goroutine
))
for
_
,
fn
:=
range
c
.
goroutine
{
...
...
@@ -301,9 +309,7 @@ func (c *Cmd) Wait() error {
}
}
for
_
,
fd
:=
range
c
.
closeAfterWait
{
fd
.
Close
()
}
c
.
closeDescriptors
(
c
.
closeAfterWait
)
if
err
!=
nil
{
return
err
...
...
libgo/go/path/filepath/path.go
View file @
08a680a8
...
...
@@ -320,8 +320,11 @@ func walk(path string, info os.FileInfo, walkFn WalkFunc) error {
}
for
_
,
fileInfo
:=
range
list
{
if
err
=
walk
(
Join
(
path
,
fileInfo
.
Name
()),
fileInfo
,
walkFn
);
err
!=
nil
{
return
err
err
=
walk
(
Join
(
path
,
fileInfo
.
Name
()),
fileInfo
,
walkFn
)
if
err
!=
nil
{
if
!
fileInfo
.
IsDir
()
||
err
!=
SkipDir
{
return
err
}
}
}
return
nil
...
...
libgo/go/path/filepath/path_plan9.go
View file @
08a680a8
...
...
@@ -12,7 +12,7 @@ func IsAbs(path string) bool {
}
// VolumeName returns the leading volume name on Windows.
// It returns "" elsewhere
// It returns "" elsewhere
.
func
VolumeName
(
path
string
)
string
{
return
""
}
...
...
libgo/go/path/filepath/path_test.go
View file @
08a680a8
...
...
@@ -869,3 +869,34 @@ func TestDriveLetterInEvalSymlinks(t *testing.T) {
t
.
Errorf
(
"Results of EvalSymlinks do not match: %q and %q"
,
flp
,
fup
)
}
}
/* This test does not work gccgo, since the sources are arranged
differently.
func TestBug3486(t *testing.T) { // http://code.google.com/p/go/issues/detail?id=3486
root, err := filepath.EvalSymlinks(os.Getenv("GOROOT"))
if err != nil {
t.Fatal(err)
}
lib := filepath.Join(root, "lib")
src := filepath.Join(root, "src")
seenSrc := false
filepath.Walk(root, func(pth string, info os.FileInfo, err error) error {
if err != nil {
t.Fatal(err)
}
switch pth {
case lib:
return filepath.SkipDir
case src:
seenSrc = true
}
return nil
})
if !seenSrc {
t.Fatalf("%q not seen", src)
}
}
*/
libgo/go/regexp/regexp.go
View file @
08a680a8
...
...
@@ -512,7 +512,7 @@ func (re *Regexp) replaceAll(bsrc []byte, src string, nmatch int, repl func(dst
}
// ReplaceAll returns a copy of src, replacing matches of the Regexp
// with the replacement
string
repl. Inside repl, $ signs are interpreted as
// with the replacement
text
repl. Inside repl, $ signs are interpreted as
// in Expand, so for instance $1 represents the text of the first submatch.
func
(
re
*
Regexp
)
ReplaceAll
(
src
,
repl
[]
byte
)
[]
byte
{
n
:=
2
...
...
@@ -726,7 +726,7 @@ func (re *Regexp) FindSubmatch(b []byte) [][]byte {
// the submatch with the corresponding index; other names refer to
// capturing parentheses named with the (?P<name>...) syntax. A
// reference to an out of range or unmatched index or a name that is not
// present in the regular expression is replaced with an empty s
tring
.
// present in the regular expression is replaced with an empty s
lice
.
//
// In the $name form, name is taken to be as long as possible: $1x is
// equivalent to ${1x}, not ${1}x, and, $10 is equivalent to ${10}, not ${1}0.
...
...
libgo/go/regexp/syntax/parse.go
View file @
08a680a8
...
...
@@ -48,6 +48,9 @@ const (
ErrTrailingBackslash
ErrorCode
=
"trailing backslash at end of expression"
)
// TODO: Export for Go 1.1.
const
errUnexpectedParen
ErrorCode
=
"unexpected )"
func
(
e
ErrorCode
)
String
()
string
{
return
string
(
e
)
}
...
...
@@ -1168,13 +1171,13 @@ func (p *parser) parseRightParen() error {
n
:=
len
(
p
.
stack
)
if
n
<
2
{
return
&
Error
{
ErrInternalError
,
""
}
return
&
Error
{
errUnexpectedParen
,
p
.
wholeRegexp
}
}
re1
:=
p
.
stack
[
n
-
1
]
re2
:=
p
.
stack
[
n
-
2
]
p
.
stack
=
p
.
stack
[
:
n
-
2
]
if
re2
.
Op
!=
opLeftParen
{
return
&
Error
{
ErrMissing
Paren
,
p
.
wholeRegexp
}
return
&
Error
{
errUnexpected
Paren
,
p
.
wholeRegexp
}
}
// Restore flags at time of paren.
p
.
flags
=
re2
.
Flags
...
...
libgo/go/regexp/syntax/parse_test.go
View file @
08a680a8
...
...
@@ -442,10 +442,18 @@ var invalidRegexps = []string{
`(`
,
`)`
,
`(a`
,
`a)`
,
`(a))`
,
`(a|b|`
,
`a|b|)`
,
`(a|b|))`
,
`(a|b`
,
`a|b)`
,
`(a|b))`
,
`[a-z`
,
`([a-z)`
,
`[a-z)`
,
`([a-z]))`
,
`x{1001}`
,
`x{9876543210}`
,
`x{2,1}`
,
...
...
libgo/go/runtime/extern.go
View file @
08a680a8
...
...
@@ -20,7 +20,7 @@ func Goexit()
// Caller reports file and line number information about function invocations on
// the calling goroutine's stack. The argument skip is the number of stack frames
// to ascend, with
1
identifying the caller of Caller. (For historical reasons the
// to ascend, with
0
identifying the caller of Caller. (For historical reasons the
// meaning of skip differs between Caller and Callers.) The return values report the
// program counter, file name, and line number within the file of the corresponding
// call. The boolean ok is false if it was not possible to recover the information.
...
...
@@ -28,7 +28,8 @@ func Caller(skip int) (pc uintptr, file string, line int, ok bool)
// Callers fills the slice pc with the program counters of function invocations
// on the calling goroutine's stack. The argument skip is the number of stack frames
// to skip before recording in pc, with 0 starting at the caller of Callers.
// to skip before recording in pc, with 0 identifying the frame for Callers itself and
// 1 identifying the caller of Callers.
// It returns the number of entries written to pc.
func
Callers
(
skip
int
,
pc
[]
uintptr
)
int
...
...
libgo/go/strconv/itoa.go
View file @
08a680a8
...
...
@@ -4,13 +4,17 @@
package
strconv
// FormatUint returns the string representation of i in the given base.
// FormatUint returns the string representation of i in the given base,
// for 2 <= base <= 36. The result uses the lower-case letters 'a' to 'z'
// for digit values >= 10.
func
FormatUint
(
i
uint64
,
base
int
)
string
{
_
,
s
:=
formatBits
(
nil
,
i
,
base
,
false
,
false
)
return
s
}
// FormatInt returns the string representation of i in the given base.
// FormatInt returns the string representation of i in the given base,
// for 2 <= base <= 36. The result uses the lower-case letters 'a' to 'z'
// for digit values >= 10.
func
FormatInt
(
i
int64
,
base
int
)
string
{
_
,
s
:=
formatBits
(
nil
,
uint64
(
i
),
base
,
i
<
0
,
false
)
return
s
...
...
libgo/go/strings/example_test.go
View file @
08a680a8
...
...
@@ -41,7 +41,6 @@ func ExampleContainsAny() {
func
ExampleCount
()
{
fmt
.
Println
(
strings
.
Count
(
"cheese"
,
"e"
))
fmt
.
Println
(
strings
.
Count
(
"five"
,
""
))
// before & after each rune
// Output:
// 3
// 5
...
...
libgo/go/text/template/exec.go
View file @
08a680a8
...
...
@@ -518,6 +518,13 @@ func (s *state) validateType(value reflect.Value, typ reflect.Type) reflect.Valu
}
}
if
!
value
.
Type
()
.
AssignableTo
(
typ
)
{
if
value
.
Kind
()
==
reflect
.
Interface
&&
!
value
.
IsNil
()
{
value
=
value
.
Elem
()
if
value
.
Type
()
.
AssignableTo
(
typ
)
{
return
value
}
// fallthrough
}
// Does one dereference or indirection work? We could do more, as we
// do with method receivers, but that gets messy and method receivers
// are much more constrained, so it makes more sense there than here.
...
...
libgo/go/text/template/exec_test.go
View file @
08a680a8
...
...
@@ -311,6 +311,7 @@ var execTests = []execTest{
{
".VariadicFuncInt"
,
"{{call .VariadicFuncInt 33 `he` `llo`}}"
,
"33=<he+llo>"
,
tVal
,
true
},
{
"if .BinaryFunc call"
,
"{{ if .BinaryFunc}}{{call .BinaryFunc `1` `2`}}{{end}}"
,
"[1=2]"
,
tVal
,
true
},
{
"if not .BinaryFunc call"
,
"{{ if not .BinaryFunc}}{{call .BinaryFunc `1` `2`}}{{else}}No{{end}}"
,
"No"
,
tVal
,
true
},
{
"Interface Call"
,
`{{stringer .S}}`
,
"foozle"
,
map
[
string
]
interface
{}{
"S"
:
bytes
.
NewBufferString
(
"foozle"
)},
true
},
// Erroneous function calls (check args).
{
".BinaryFuncTooFew"
,
"{{call .BinaryFunc `1`}}"
,
""
,
tVal
,
false
},
...
...
@@ -507,6 +508,10 @@ func vfunc(V, *V) string {
return
"vfunc"
}
func
stringer
(
s
fmt
.
Stringer
)
string
{
return
s
.
String
()
}
func
testExecute
(
execTests
[]
execTest
,
template
*
Template
,
t
*
testing
.
T
)
{
b
:=
new
(
bytes
.
Buffer
)
funcs
:=
FuncMap
{
...
...
@@ -516,6 +521,7 @@ func testExecute(execTests []execTest, template *Template, t *testing.T) {
"typeOf"
:
typeOf
,
"vfunc"
:
vfunc
,
"zeroArgs"
:
zeroArgs
,
"stringer"
:
stringer
,
}
for
_
,
test
:=
range
execTests
{
var
tmpl
*
Template
...
...
libgo/go/time/sleep_test.go
View file @
08a680a8
...
...
@@ -224,3 +224,25 @@ func TestTimerStopStress(t *testing.T) {
}
Sleep
(
3
*
Second
)
}
func
TestSleepZeroDeadlock
(
t
*
testing
.
T
)
{
// Sleep(0) used to hang, the sequence of events was as follows.
// Sleep(0) sets G's status to Gwaiting, but then immediately returns leaving the status.
// Then the goroutine calls e.g. new and falls down into the scheduler due to pending GC.
// After the GC nobody wakes up the goroutine from Gwaiting status.
defer
runtime
.
GOMAXPROCS
(
runtime
.
GOMAXPROCS
(
4
))
c
:=
make
(
chan
bool
)
go
func
()
{
for
i
:=
0
;
i
<
100
;
i
++
{
runtime
.
GC
()
}
c
<-
true
}()
for
i
:=
0
;
i
<
100
;
i
++
{
Sleep
(
0
)
tmp
:=
make
(
chan
bool
,
1
)
tmp
<-
true
<-
tmp
}
<-
c
}
libgo/go/unicode/tables.go
View file @
08a680a8
...
...
@@ -2701,7 +2701,7 @@ var _Zs = &RangeTable{
},
}
// The
following variables are of type *RangeTable:
// The
se variables have type *RangeTable.
var
(
Cc
=
_Cc
// Cc is the set of Unicode characters in category Cc.
Cf
=
_Cf
// Cf is the set of Unicode characters in category Cf.
...
...
@@ -4054,7 +4054,7 @@ var _Yi = &RangeTable{
},
}
// The
following variables are of type *RangeTable:
// The
se variables have type *RangeTable.
var
(
Arabic
=
_Arabic
// Arabic is the set of Unicode characters in script Arabic.
Armenian
=
_Armenian
// Armenian is the set of Unicode characters in script Armenian.
...
...
@@ -5116,7 +5116,7 @@ var _White_Space = &RangeTable{
},
}
// The
following variables are of type *RangeTable:
// The
se variables have type *RangeTable.
var
(
ASCII_Hex_Digit
=
_ASCII_Hex_Digit
// ASCII_Hex_Digit is the set of Unicode characters with property ASCII_Hex_Digit.
Bidi_Control
=
_Bidi_Control
// Bidi_Control is the set of Unicode characters with property Bidi_Control.
...
...
libgo/runtime/malloc.goc
View file @
08a680a8
...
...
@@ -168,6 +168,7 @@ __go_free(void *v)
c->local_by_size[sizeclass].nfree++;
runtime_MCache_Free(c, v, sizeclass, size);
}
c->local_nfree++;
c->local_alloc -= size;
if(prof)
runtime_MProf_Free(v, size);
...
...
libgo/runtime/mfinal.c
View file @
08a680a8
...
...
@@ -150,8 +150,7 @@ runtime_addfinalizer(void *p, void (*f)(void*), const struct __go_func_type *ft)
tab
=
TAB
(
p
);
runtime_lock
(
tab
);
if
(
f
==
nil
)
{
if
(
lookfintab
(
tab
,
p
,
true
,
nil
))
runtime_setblockspecial
(
p
,
false
);
lookfintab
(
tab
,
p
,
true
,
nil
);
runtime_unlock
(
tab
);
return
true
;
}
...
...
libgo/runtime/mgc0.c
View file @
08a680a8
...
...
@@ -1132,7 +1132,6 @@ runfinq(void* dummy __attribute__ ((unused)))
f
=
&
fb
->
fin
[
i
];
params
[
0
]
=
&
f
->
arg
;
runtime_setblockspecial
(
f
->
arg
,
false
);
reflect_call
(
f
->
ft
,
(
void
*
)
f
->
fn
,
0
,
0
,
params
,
nil
);
f
->
fn
=
nil
;
f
->
arg
=
nil
;
...
...
libgo/runtime/time.goc
View file @
08a680a8
...
...
@@ -61,15 +61,21 @@ ready(int64 now, Eface e)
void
runtime_tsleep(int64 ns)
{
G* g;
Timer t;
if(ns <= 0)
g = runtime_g();
if(ns <= 0) {
g->status = Grunning;
g->waitreason = nil;
return;
}
t.when = runtime_nanotime() + ns;
t.period = 0;
t.f = ready;
t.arg.__object =
runtime_g()
;
t.arg.__object =
g
;
addtimer(&t);
runtime_gosched();
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment