mirror of
https://github.com/golang/go.git
synced 2025-05-30 19:52:53 +00:00
[dev.garbage] all: merge default into dev.garbage
This picks up the selectdone dangling pointer fix, among others. LGTM=rlh R=rlh CC=golang-codereviews https://golang.org/cl/153070045
This commit is contained in:
commit
9ba99011fa
@ -21,6 +21,7 @@ cmd/go: compile and link all _test.go files during 'go test', even in packages w
|
||||
asm: make textflag.h available outside of cmd/ld (CL 128050043)
|
||||
crypto/tls: add support for ALPN (RFC 7301) (CL 108710046)
|
||||
crypto/tls: support programmatic selection of server certificates (CL 107400043)
|
||||
fmt: print type *map[T]T as &map[k:v] (CL 154870043)
|
||||
encoding/gob: remove unsafe (CL 102680045)
|
||||
misc: deleted editor support; refer to https://code.google.com/p/go-wiki/wiki/IDEsAndTextEditorPlugins instead (CL 105470043)
|
||||
net/http: add Request.BasicAuth method (CL 76540043)
|
||||
@ -29,9 +30,10 @@ net/http/httputil: add ReverseProxy.ErrorLog (CL 132750043)
|
||||
os: implement symlink support for windows (CL 86160044)
|
||||
reflect: add type.Comparable (CL 144020043)
|
||||
runtime: implement monotonic clocks on windows (CL 108700045)
|
||||
runtime: stack size 2K (4K on plan 9 and windows) (CL 145790043)
|
||||
runtime: memory consumption is reduced by 10-30% (CL 106260045 removes type info from heap, CL 145790043 reduces stack size to 2K (4K on plan 9 and windows))
|
||||
runtime: MemStats.Mallocs now counts very small allocations missed in Go 1.3. This may break tests using runtime.ReadMemStats or testing.AllocsPerRun by giving a more accurate answer than Go 1.3 did (CL 143150043).
|
||||
runtime/race: freebsd is supported (CL 107270043)
|
||||
swig: Due to runtime changes Go 1.4 will require SWIG 3.0.3 (not yet released)
|
||||
sync/atomic: add Value (CL 136710045)
|
||||
syscall: Setuid, Setgid are disabled on linux platforms. On linux those syscalls operate on the calling thread, not the whole process. This does not match the semantics of other platforms, nor the expectations of the caller, so the operations have been disabled until issue 1435 is resolved (CL 106170043)
|
||||
syscall: now frozen (CL 129820043)
|
||||
|
@ -29,6 +29,7 @@ static void issue7978c(uint32_t *sync) {
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
@ -81,6 +82,9 @@ func issue7978go() {
|
||||
}
|
||||
|
||||
func test7978(t *testing.T) {
|
||||
if os.Getenv("GOTRACEBACK") != "2" {
|
||||
t.Fatalf("GOTRACEBACK must be 2")
|
||||
}
|
||||
issue7978sync = 0
|
||||
go issue7978go()
|
||||
// test in c code, before callback
|
||||
|
@ -1043,6 +1043,7 @@ complex:
|
||||
}
|
||||
| LSTRUCT sbody
|
||||
{
|
||||
diag(Z, "struct must have tag");
|
||||
taggen++;
|
||||
sprint(symb, "_%d_", taggen);
|
||||
$$ = dotag(lookup(), TSTRUCT, autobn);
|
||||
|
1149
src/cmd/cc/y.tab.c
1149
src/cmd/cc/y.tab.c
File diff suppressed because it is too large
Load Diff
@ -1,21 +1,24 @@
|
||||
/* A Bison parser, made by GNU Bison 2.7.12-4996. */
|
||||
/* A Bison parser, made by GNU Bison 2.3. */
|
||||
|
||||
/* Bison interface for Yacc-like parsers in C
|
||||
|
||||
Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
/* Skeleton interface for Bison's Yacc-like parsers in C
|
||||
|
||||
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
|
||||
/* As a special exception, you may create a larger work that contains
|
||||
part or all of the Bison parser skeleton and distribute that work
|
||||
@ -26,20 +29,10 @@
|
||||
special exception, which will cause the skeleton and the resulting
|
||||
Bison output files to be licensed under the GNU General Public
|
||||
License without this special exception.
|
||||
|
||||
|
||||
This special exception was added by the Free Software Foundation in
|
||||
version 2.2 of Bison. */
|
||||
|
||||
#ifndef YY_YY_Y_TAB_H_INCLUDED
|
||||
# define YY_YY_Y_TAB_H_INCLUDED
|
||||
/* Enabling traces. */
|
||||
#ifndef YYDEBUG
|
||||
# define YYDEBUG 0
|
||||
#endif
|
||||
#if YYDEBUG
|
||||
extern int yydebug;
|
||||
#endif
|
||||
|
||||
/* Tokens. */
|
||||
#ifndef YYTOKENTYPE
|
||||
# define YYTOKENTYPE
|
||||
@ -196,12 +189,11 @@ extern int yydebug;
|
||||
|
||||
|
||||
|
||||
|
||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||
typedef union YYSTYPE
|
||||
{
|
||||
/* Line 2053 of yacc.c */
|
||||
#line 36 "cc.y"
|
||||
|
||||
{
|
||||
Node* node;
|
||||
Sym* sym;
|
||||
Type* type;
|
||||
@ -225,30 +217,14 @@ typedef union YYSTYPE
|
||||
int32 lval;
|
||||
double dval;
|
||||
vlong vval;
|
||||
|
||||
|
||||
/* Line 2053 of yacc.c */
|
||||
#line 232 "y.tab.h"
|
||||
} YYSTYPE;
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
}
|
||||
/* Line 1529 of yacc.c. */
|
||||
#line 223 "y.tab.h"
|
||||
YYSTYPE;
|
||||
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
#endif
|
||||
|
||||
extern YYSTYPE yylval;
|
||||
|
||||
#ifdef YYPARSE_PARAM
|
||||
#if defined __STDC__ || defined __cplusplus
|
||||
int yyparse (void *YYPARSE_PARAM);
|
||||
#else
|
||||
int yyparse ();
|
||||
#endif
|
||||
#else /* ! YYPARSE_PARAM */
|
||||
#if defined __STDC__ || defined __cplusplus
|
||||
int yyparse (void);
|
||||
#else
|
||||
int yyparse ();
|
||||
#endif
|
||||
#endif /* ! YYPARSE_PARAM */
|
||||
|
||||
#endif /* !YY_YY_Y_TAB_H_INCLUDED */
|
||||
|
@ -15,6 +15,7 @@ var certFiles = []string{
|
||||
"/etc/ssl/ca-bundle.pem", // OpenSUSE
|
||||
"/etc/ssl/cert.pem", // OpenBSD
|
||||
"/usr/local/share/certs/ca-root-nss.crt", // FreeBSD/DragonFly
|
||||
"/etc/pki/tls/cacert.pem", // OpenELEC
|
||||
}
|
||||
|
||||
// Possible directories with certificate files; stop after successfully
|
||||
|
@ -13,7 +13,7 @@
|
||||
The verbs:
|
||||
|
||||
General:
|
||||
%v the value in a default format.
|
||||
%v the value in a default format
|
||||
when printing structs, the plus flag (%+v) adds field names
|
||||
%#v a Go-syntax representation of the value
|
||||
%T a Go-syntax representation of the type of the value
|
||||
@ -51,6 +51,21 @@
|
||||
There is no 'u' flag. Integers are printed unsigned if they have unsigned type.
|
||||
Similarly, there is no need to specify the size of the operand (int8, int64).
|
||||
|
||||
The default format for %v is:
|
||||
bool: %t
|
||||
int, int8 etc.: %d
|
||||
uint, uint8 etc.: %d, %x if printed with %#v
|
||||
float32, complex64, etc: %g
|
||||
string: %s
|
||||
chan: %p
|
||||
pointer: %p
|
||||
For compound objects, the elements are printed using these rules, recursively,
|
||||
laid out like this:
|
||||
struct: {field0 field1 ...}
|
||||
array, slice: [elem0 elem1 ...]
|
||||
maps: map[key1:value1 key2:value2]
|
||||
pointer to above: &{}, &[], &map[]
|
||||
|
||||
Width is specified by an optional decimal number immediately following the verb.
|
||||
If absent, the width is whatever is necessary to represent the value.
|
||||
Precision is specified after the (optional) width by a period followed by a
|
||||
|
@ -919,7 +919,7 @@ func TestCountMallocs(t *testing.T) {
|
||||
|
||||
type flagPrinter struct{}
|
||||
|
||||
func (*flagPrinter) Format(f State, c rune) {
|
||||
func (flagPrinter) Format(f State, c rune) {
|
||||
s := "%"
|
||||
for i := 0; i < 128; i++ {
|
||||
if f.Flag(i) {
|
||||
@ -965,11 +965,12 @@ func TestFlagParser(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestStructPrinter(t *testing.T) {
|
||||
var s struct {
|
||||
type T struct {
|
||||
a string
|
||||
b string
|
||||
c int
|
||||
}
|
||||
var s T
|
||||
s.a = "abc"
|
||||
s.b = "def"
|
||||
s.c = 123
|
||||
@ -979,12 +980,35 @@ func TestStructPrinter(t *testing.T) {
|
||||
}{
|
||||
{"%v", "{abc def 123}"},
|
||||
{"%+v", "{a:abc b:def c:123}"},
|
||||
{"%#v", `fmt_test.T{a:"abc", b:"def", c:123}`},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
out := Sprintf(tt.fmt, s)
|
||||
if out != tt.out {
|
||||
t.Errorf("Sprintf(%q, &s) = %q, want %q", tt.fmt, out, tt.out)
|
||||
t.Errorf("Sprintf(%q, s) = %#q, want %#q", tt.fmt, out, tt.out)
|
||||
}
|
||||
// The same but with a pointer.
|
||||
out = Sprintf(tt.fmt, &s)
|
||||
if out != "&"+tt.out {
|
||||
t.Errorf("Sprintf(%q, &s) = %#q, want %#q", tt.fmt, out, "&"+tt.out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSlicePrinter(t *testing.T) {
|
||||
slice := []int{}
|
||||
s := Sprint(slice)
|
||||
if s != "[]" {
|
||||
t.Errorf("empty slice printed as %q not %q", s, "[]")
|
||||
}
|
||||
slice = []int{1, 2, 3}
|
||||
s = Sprint(slice)
|
||||
if s != "[1 2 3]" {
|
||||
t.Errorf("slice: got %q expected %q", s, "[1 2 3]")
|
||||
}
|
||||
s = Sprint(&slice)
|
||||
if s != "&[1 2 3]" {
|
||||
t.Errorf("&slice: got %q expected %q", s, "&[1 2 3]")
|
||||
}
|
||||
}
|
||||
|
||||
@ -1014,6 +1038,12 @@ func TestMapPrinter(t *testing.T) {
|
||||
a := []string{"1:one", "2:two", "3:three"}
|
||||
presentInMap(Sprintf("%v", m1), a, t)
|
||||
presentInMap(Sprint(m1), a, t)
|
||||
// Pointer to map prints the same but with initial &.
|
||||
if !strings.HasPrefix(Sprint(&m1), "&") {
|
||||
t.Errorf("no initial & for address of map")
|
||||
}
|
||||
presentInMap(Sprintf("%v", &m1), a, t)
|
||||
presentInMap(Sprint(&m1), a, t)
|
||||
}
|
||||
|
||||
func TestEmptyMap(t *testing.T) {
|
||||
@ -1208,86 +1238,66 @@ func TestNilDoesNotBecomeTyped(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// Formatters did not get delivered flags correctly in all cases. Issue 8835.
|
||||
type fp struct{}
|
||||
|
||||
func (fp) Format(f State, c rune) {
|
||||
s := "%"
|
||||
for i := 0; i < 128; i++ {
|
||||
if f.Flag(i) {
|
||||
s += string(i)
|
||||
}
|
||||
}
|
||||
if w, ok := f.Width(); ok {
|
||||
s += Sprintf("%d", w)
|
||||
}
|
||||
if p, ok := f.Precision(); ok {
|
||||
s += Sprintf(".%d", p)
|
||||
}
|
||||
s += string(c)
|
||||
io.WriteString(f, "["+s+"]")
|
||||
}
|
||||
|
||||
var formatterFlagTests = []struct {
|
||||
in string
|
||||
val interface{}
|
||||
out string
|
||||
}{
|
||||
// scalar values with the (unused by fmt) 'a' verb.
|
||||
{"%a", fp{}, "[%a]"},
|
||||
{"%-a", fp{}, "[%-a]"},
|
||||
{"%+a", fp{}, "[%+a]"},
|
||||
{"%#a", fp{}, "[%#a]"},
|
||||
{"% a", fp{}, "[% a]"},
|
||||
{"%0a", fp{}, "[%0a]"},
|
||||
{"%1.2a", fp{}, "[%1.2a]"},
|
||||
{"%-1.2a", fp{}, "[%-1.2a]"},
|
||||
{"%+1.2a", fp{}, "[%+1.2a]"},
|
||||
{"%-+1.2a", fp{}, "[%+-1.2a]"},
|
||||
{"%-+1.2abc", fp{}, "[%+-1.2a]bc"},
|
||||
{"%-1.2abc", fp{}, "[%-1.2a]bc"},
|
||||
{"%a", flagPrinter{}, "[%a]"},
|
||||
{"%-a", flagPrinter{}, "[%-a]"},
|
||||
{"%+a", flagPrinter{}, "[%+a]"},
|
||||
{"%#a", flagPrinter{}, "[%#a]"},
|
||||
{"% a", flagPrinter{}, "[% a]"},
|
||||
{"%0a", flagPrinter{}, "[%0a]"},
|
||||
{"%1.2a", flagPrinter{}, "[%1.2a]"},
|
||||
{"%-1.2a", flagPrinter{}, "[%-1.2a]"},
|
||||
{"%+1.2a", flagPrinter{}, "[%+1.2a]"},
|
||||
{"%-+1.2a", flagPrinter{}, "[%+-1.2a]"},
|
||||
{"%-+1.2abc", flagPrinter{}, "[%+-1.2a]bc"},
|
||||
{"%-1.2abc", flagPrinter{}, "[%-1.2a]bc"},
|
||||
|
||||
// composite values with the 'a' verb
|
||||
{"%a", [1]fp{}, "[[%a]]"},
|
||||
{"%-a", [1]fp{}, "[[%-a]]"},
|
||||
{"%+a", [1]fp{}, "[[%+a]]"},
|
||||
{"%#a", [1]fp{}, "[[%#a]]"},
|
||||
{"% a", [1]fp{}, "[[% a]]"},
|
||||
{"%0a", [1]fp{}, "[[%0a]]"},
|
||||
{"%1.2a", [1]fp{}, "[[%1.2a]]"},
|
||||
{"%-1.2a", [1]fp{}, "[[%-1.2a]]"},
|
||||
{"%+1.2a", [1]fp{}, "[[%+1.2a]]"},
|
||||
{"%-+1.2a", [1]fp{}, "[[%+-1.2a]]"},
|
||||
{"%-+1.2abc", [1]fp{}, "[[%+-1.2a]]bc"},
|
||||
{"%-1.2abc", [1]fp{}, "[[%-1.2a]]bc"},
|
||||
{"%a", [1]flagPrinter{}, "[[%a]]"},
|
||||
{"%-a", [1]flagPrinter{}, "[[%-a]]"},
|
||||
{"%+a", [1]flagPrinter{}, "[[%+a]]"},
|
||||
{"%#a", [1]flagPrinter{}, "[[%#a]]"},
|
||||
{"% a", [1]flagPrinter{}, "[[% a]]"},
|
||||
{"%0a", [1]flagPrinter{}, "[[%0a]]"},
|
||||
{"%1.2a", [1]flagPrinter{}, "[[%1.2a]]"},
|
||||
{"%-1.2a", [1]flagPrinter{}, "[[%-1.2a]]"},
|
||||
{"%+1.2a", [1]flagPrinter{}, "[[%+1.2a]]"},
|
||||
{"%-+1.2a", [1]flagPrinter{}, "[[%+-1.2a]]"},
|
||||
{"%-+1.2abc", [1]flagPrinter{}, "[[%+-1.2a]]bc"},
|
||||
{"%-1.2abc", [1]flagPrinter{}, "[[%-1.2a]]bc"},
|
||||
|
||||
// simple values with the 'v' verb
|
||||
{"%v", fp{}, "[%v]"},
|
||||
{"%-v", fp{}, "[%-v]"},
|
||||
{"%+v", fp{}, "[%+v]"},
|
||||
{"%#v", fp{}, "[%#v]"},
|
||||
{"% v", fp{}, "[% v]"},
|
||||
{"%0v", fp{}, "[%0v]"},
|
||||
{"%1.2v", fp{}, "[%1.2v]"},
|
||||
{"%-1.2v", fp{}, "[%-1.2v]"},
|
||||
{"%+1.2v", fp{}, "[%+1.2v]"},
|
||||
{"%-+1.2v", fp{}, "[%+-1.2v]"},
|
||||
{"%-+1.2vbc", fp{}, "[%+-1.2v]bc"},
|
||||
{"%-1.2vbc", fp{}, "[%-1.2v]bc"},
|
||||
{"%v", flagPrinter{}, "[%v]"},
|
||||
{"%-v", flagPrinter{}, "[%-v]"},
|
||||
{"%+v", flagPrinter{}, "[%+v]"},
|
||||
{"%#v", flagPrinter{}, "[%#v]"},
|
||||
{"% v", flagPrinter{}, "[% v]"},
|
||||
{"%0v", flagPrinter{}, "[%0v]"},
|
||||
{"%1.2v", flagPrinter{}, "[%1.2v]"},
|
||||
{"%-1.2v", flagPrinter{}, "[%-1.2v]"},
|
||||
{"%+1.2v", flagPrinter{}, "[%+1.2v]"},
|
||||
{"%-+1.2v", flagPrinter{}, "[%+-1.2v]"},
|
||||
{"%-+1.2vbc", flagPrinter{}, "[%+-1.2v]bc"},
|
||||
{"%-1.2vbc", flagPrinter{}, "[%-1.2v]bc"},
|
||||
|
||||
// composite values with the 'v' verb. Some are still broken.
|
||||
{"%v", [1]fp{}, "[[%v]]"},
|
||||
{"%-v", [1]fp{}, "[[%-v]]"},
|
||||
//{"%+v", [1]fp{}, "[[%+v]]"},
|
||||
{"%#v", [1]fp{}, "[1]fmt_test.fp{[%#v]}"},
|
||||
{"% v", [1]fp{}, "[[% v]]"},
|
||||
{"%0v", [1]fp{}, "[[%0v]]"},
|
||||
{"%1.2v", [1]fp{}, "[[%1.2v]]"},
|
||||
{"%-1.2v", [1]fp{}, "[[%-1.2v]]"},
|
||||
//{"%+1.2v", [1]fp{}, "[[%+1.2v]]"},
|
||||
//{"%-+1.2v", [1]fp{}, "[[%+-1.2v]]"},
|
||||
//{"%-+1.2vbc", [1]fp{}, "[[%+-1.2v]]bc"},
|
||||
{"%-1.2vbc", [1]fp{}, "[[%-1.2v]]bc"},
|
||||
// composite values with the 'v' verb.
|
||||
{"%v", [1]flagPrinter{}, "[[%v]]"},
|
||||
{"%-v", [1]flagPrinter{}, "[[%-v]]"},
|
||||
{"%+v", [1]flagPrinter{}, "[[%+v]]"},
|
||||
{"%#v", [1]flagPrinter{}, "[1]fmt_test.flagPrinter{[%#v]}"},
|
||||
{"% v", [1]flagPrinter{}, "[[% v]]"},
|
||||
{"%0v", [1]flagPrinter{}, "[[%0v]]"},
|
||||
{"%1.2v", [1]flagPrinter{}, "[[%1.2v]]"},
|
||||
{"%-1.2v", [1]flagPrinter{}, "[[%-1.2v]]"},
|
||||
{"%+1.2v", [1]flagPrinter{}, "[[%+1.2v]]"},
|
||||
{"%-+1.2v", [1]flagPrinter{}, "[[%+-1.2v]]"},
|
||||
{"%-+1.2vbc", [1]flagPrinter{}, "[[%+-1.2v]]bc"},
|
||||
{"%-1.2vbc", [1]flagPrinter{}, "[[%-1.2v]]bc"},
|
||||
}
|
||||
|
||||
func TestFormatterFlags(t *testing.T) {
|
||||
|
@ -34,6 +34,25 @@ func init() {
|
||||
}
|
||||
}
|
||||
|
||||
// flags placed in a separate struct for easy clearing.
|
||||
type fmtFlags struct {
|
||||
widPresent bool
|
||||
precPresent bool
|
||||
minus bool
|
||||
plus bool
|
||||
sharp bool
|
||||
space bool
|
||||
unicode bool
|
||||
uniQuote bool // Use 'x'= prefix for %U if printable.
|
||||
zero bool
|
||||
|
||||
// For the formats %+v %#v, we set the plusV/sharpV flags
|
||||
// and clear the plus/sharp flags since %+v and %#v are in effect
|
||||
// different, flagless formats set at the top level.
|
||||
plusV bool
|
||||
sharpV bool
|
||||
}
|
||||
|
||||
// A fmt is the raw formatter used by Printf etc.
|
||||
// It prints into a buffer that must be set up separately.
|
||||
type fmt struct {
|
||||
@ -42,36 +61,11 @@ type fmt struct {
|
||||
// width, precision
|
||||
wid int
|
||||
prec int
|
||||
// flags
|
||||
widPresent bool
|
||||
precPresent bool
|
||||
minus bool
|
||||
plus bool
|
||||
sharp bool
|
||||
space bool
|
||||
// For the format %#v, we set this flag and
|
||||
// clear the plus flag, since it is in effect
|
||||
// a different, flagless format set at the top level.
|
||||
// TODO: plusV could use this too.
|
||||
sharpV bool
|
||||
unicode bool
|
||||
uniQuote bool // Use 'x'= prefix for %U if printable.
|
||||
zero bool
|
||||
fmtFlags
|
||||
}
|
||||
|
||||
func (f *fmt) clearflags() {
|
||||
f.wid = 0
|
||||
f.widPresent = false
|
||||
f.prec = 0
|
||||
f.precPresent = false
|
||||
f.minus = false
|
||||
f.plus = false
|
||||
f.sharp = false
|
||||
f.space = false
|
||||
f.sharpV = false
|
||||
f.unicode = false
|
||||
f.uniQuote = false
|
||||
f.zero = false
|
||||
f.fmtFlags = fmtFlags{}
|
||||
}
|
||||
|
||||
func (f *fmt) init(buf *buffer) {
|
||||
|
115
src/fmt/print.go
115
src/fmt/print.go
@ -128,7 +128,7 @@ var ppFree = sync.Pool{
|
||||
New: func() interface{} { return new(pp) },
|
||||
}
|
||||
|
||||
// newPrinter allocates a new pp struct or grab a cached one.
|
||||
// newPrinter allocates a new pp struct or grabs a cached one.
|
||||
func newPrinter() *pp {
|
||||
p := ppFree.Get().(*pp)
|
||||
p.panicking = false
|
||||
@ -317,11 +317,11 @@ func (p *pp) badVerb(verb rune) {
|
||||
case p.arg != nil:
|
||||
p.buf.WriteString(reflect.TypeOf(p.arg).String())
|
||||
p.add('=')
|
||||
p.printArg(p.arg, 'v', false, 0)
|
||||
p.printArg(p.arg, 'v', 0)
|
||||
case p.value.IsValid():
|
||||
p.buf.WriteString(p.value.Type().String())
|
||||
p.add('=')
|
||||
p.printValue(p.value, 'v', false, 0)
|
||||
p.printValue(p.value, 'v', 0)
|
||||
default:
|
||||
p.buf.Write(nilAngleBytes)
|
||||
}
|
||||
@ -549,7 +549,7 @@ func (p *pp) fmtBytes(v []byte, verb rune, typ reflect.Type, depth int) {
|
||||
p.buf.WriteByte(' ')
|
||||
}
|
||||
}
|
||||
p.printArg(c, 'v', p.fmt.plus, depth+1)
|
||||
p.printArg(c, 'v', depth+1)
|
||||
}
|
||||
if p.fmt.sharpV {
|
||||
p.buf.WriteByte('}')
|
||||
@ -641,32 +641,41 @@ func (p *pp) catchPanic(arg interface{}, verb rune) {
|
||||
p.add(verb)
|
||||
p.buf.Write(panicBytes)
|
||||
p.panicking = true
|
||||
p.printArg(err, 'v', false, 0)
|
||||
p.printArg(err, 'v', 0)
|
||||
p.panicking = false
|
||||
p.buf.WriteByte(')')
|
||||
}
|
||||
}
|
||||
|
||||
// clearSpecialFlags pushes %#v back into the regular flags and returns their old state.
|
||||
func (p *pp) clearSpecialFlags() bool {
|
||||
ret := p.fmt.sharpV
|
||||
if ret {
|
||||
func (p *pp) clearSpecialFlags() (plusV, sharpV bool) {
|
||||
plusV = p.fmt.plusV
|
||||
if plusV {
|
||||
p.fmt.plus = true
|
||||
p.fmt.plusV = false
|
||||
}
|
||||
sharpV = p.fmt.sharpV
|
||||
if sharpV {
|
||||
p.fmt.sharp = true
|
||||
p.fmt.sharpV = false
|
||||
}
|
||||
return ret
|
||||
return
|
||||
}
|
||||
|
||||
// restoreSpecialFlags, whose argument should be a call to clearSpecialFlags,
|
||||
// restores the setting of the sharpV flag.
|
||||
func (p *pp) restoreSpecialFlags(sharpV bool) {
|
||||
// restores the setting of the plusV and sharpV flags.
|
||||
func (p *pp) restoreSpecialFlags(plusV, sharpV bool) {
|
||||
if plusV {
|
||||
p.fmt.plus = false
|
||||
p.fmt.plusV = true
|
||||
}
|
||||
if sharpV {
|
||||
p.fmt.sharp = false
|
||||
p.fmt.sharpV = true
|
||||
}
|
||||
}
|
||||
|
||||
func (p *pp) handleMethods(verb rune, plus bool, depth int) (handled bool) {
|
||||
func (p *pp) handleMethods(verb rune, depth int) (handled bool) {
|
||||
if p.erroring {
|
||||
return
|
||||
}
|
||||
@ -678,19 +687,14 @@ func (p *pp) handleMethods(verb rune, plus bool, depth int) (handled bool) {
|
||||
formatter.Format(p, verb)
|
||||
return
|
||||
}
|
||||
// Must not touch flags before Formatter looks at them.
|
||||
if plus {
|
||||
p.fmt.plus = false
|
||||
}
|
||||
|
||||
// If we're doing Go syntax and the argument knows how to supply it, take care of it now.
|
||||
if p.fmt.sharpV {
|
||||
if stringer, ok := p.arg.(GoStringer); ok {
|
||||
handled = true
|
||||
defer p.restoreSpecialFlags(p.clearSpecialFlags())
|
||||
defer p.catchPanic(p.arg, verb)
|
||||
// Print the result of GoString unadorned.
|
||||
p.fmtString(stringer.GoString(), 's')
|
||||
p.fmt.fmt_s(stringer.GoString())
|
||||
return
|
||||
}
|
||||
} else {
|
||||
@ -707,13 +711,13 @@ func (p *pp) handleMethods(verb rune, plus bool, depth int) (handled bool) {
|
||||
case error:
|
||||
handled = true
|
||||
defer p.catchPanic(p.arg, verb)
|
||||
p.printArg(v.Error(), verb, plus, depth)
|
||||
p.printArg(v.Error(), verb, depth)
|
||||
return
|
||||
|
||||
case Stringer:
|
||||
handled = true
|
||||
defer p.catchPanic(p.arg, verb)
|
||||
p.printArg(v.String(), verb, plus, depth)
|
||||
p.printArg(v.String(), verb, depth)
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -721,7 +725,7 @@ func (p *pp) handleMethods(verb rune, plus bool, depth int) (handled bool) {
|
||||
return false
|
||||
}
|
||||
|
||||
func (p *pp) printArg(arg interface{}, verb rune, plus bool, depth int) (wasString bool) {
|
||||
func (p *pp) printArg(arg interface{}, verb rune, depth int) (wasString bool) {
|
||||
p.arg = arg
|
||||
p.value = reflect.Value{}
|
||||
|
||||
@ -738,22 +742,13 @@ func (p *pp) printArg(arg interface{}, verb rune, plus bool, depth int) (wasStri
|
||||
// %T (the value's type) and %p (its address) are special; we always do them first.
|
||||
switch verb {
|
||||
case 'T':
|
||||
p.printArg(reflect.TypeOf(arg).String(), 's', false, 0)
|
||||
p.printArg(reflect.TypeOf(arg).String(), 's', 0)
|
||||
return false
|
||||
case 'p':
|
||||
p.fmtPointer(reflect.ValueOf(arg), verb)
|
||||
return false
|
||||
}
|
||||
|
||||
// Clear flags for base formatters.
|
||||
// handleMethods needs them, so we must restore them later.
|
||||
// We could call handleMethods here and avoid this work, but
|
||||
// handleMethods is expensive enough to be worth delaying.
|
||||
oldPlus := p.fmt.plus
|
||||
if plus {
|
||||
p.fmt.plus = false
|
||||
}
|
||||
|
||||
// Some types can be done without reflection.
|
||||
switch f := arg.(type) {
|
||||
case bool:
|
||||
@ -795,21 +790,19 @@ func (p *pp) printArg(arg interface{}, verb rune, plus bool, depth int) (wasStri
|
||||
p.fmtBytes(f, verb, nil, depth)
|
||||
wasString = verb == 's'
|
||||
default:
|
||||
// Restore flags in case handleMethods finds a Formatter.
|
||||
p.fmt.plus = oldPlus
|
||||
// If the type is not simple, it might have methods.
|
||||
if handled := p.handleMethods(verb, plus, depth); handled {
|
||||
if handled := p.handleMethods(verb, depth); handled {
|
||||
return false
|
||||
}
|
||||
// Need to use reflection
|
||||
return p.printReflectValue(reflect.ValueOf(arg), verb, plus, depth)
|
||||
return p.printReflectValue(reflect.ValueOf(arg), verb, depth)
|
||||
}
|
||||
p.arg = nil
|
||||
return
|
||||
}
|
||||
|
||||
// printValue is like printArg but starts with a reflect value, not an interface{} value.
|
||||
func (p *pp) printValue(value reflect.Value, verb rune, plus bool, depth int) (wasString bool) {
|
||||
func (p *pp) printValue(value reflect.Value, verb rune, depth int) (wasString bool) {
|
||||
if !value.IsValid() {
|
||||
if verb == 'T' || verb == 'v' {
|
||||
p.buf.Write(nilAngleBytes)
|
||||
@ -823,7 +816,7 @@ func (p *pp) printValue(value reflect.Value, verb rune, plus bool, depth int) (w
|
||||
// %T (the value's type) and %p (its address) are special; we always do them first.
|
||||
switch verb {
|
||||
case 'T':
|
||||
p.printArg(value.Type().String(), 's', false, 0)
|
||||
p.printArg(value.Type().String(), 's', 0)
|
||||
return false
|
||||
case 'p':
|
||||
p.fmtPointer(value, verb)
|
||||
@ -836,18 +829,18 @@ func (p *pp) printValue(value reflect.Value, verb rune, plus bool, depth int) (w
|
||||
if value.CanInterface() {
|
||||
p.arg = value.Interface()
|
||||
}
|
||||
if handled := p.handleMethods(verb, plus, depth); handled {
|
||||
if handled := p.handleMethods(verb, depth); handled {
|
||||
return false
|
||||
}
|
||||
|
||||
return p.printReflectValue(value, verb, plus, depth)
|
||||
return p.printReflectValue(value, verb, depth)
|
||||
}
|
||||
|
||||
var byteType = reflect.TypeOf(byte(0))
|
||||
|
||||
// printReflectValue is the fallback for both printArg and printValue.
|
||||
// It uses reflect to print the value.
|
||||
func (p *pp) printReflectValue(value reflect.Value, verb rune, plus bool, depth int) (wasString bool) {
|
||||
func (p *pp) printReflectValue(value reflect.Value, verb rune, depth int) (wasString bool) {
|
||||
oldValue := p.value
|
||||
p.value = value
|
||||
BigSwitch:
|
||||
@ -892,9 +885,9 @@ BigSwitch:
|
||||
p.buf.WriteByte(' ')
|
||||
}
|
||||
}
|
||||
p.printValue(key, verb, plus, depth+1)
|
||||
p.printValue(key, verb, depth+1)
|
||||
p.buf.WriteByte(':')
|
||||
p.printValue(f.MapIndex(key), verb, plus, depth+1)
|
||||
p.printValue(f.MapIndex(key), verb, depth+1)
|
||||
}
|
||||
if p.fmt.sharpV {
|
||||
p.buf.WriteByte('}')
|
||||
@ -916,13 +909,13 @@ BigSwitch:
|
||||
p.buf.WriteByte(' ')
|
||||
}
|
||||
}
|
||||
if plus || p.fmt.sharpV {
|
||||
if p.fmt.plusV || p.fmt.sharpV {
|
||||
if f := t.Field(i); f.Name != "" {
|
||||
p.buf.WriteString(f.Name)
|
||||
p.buf.WriteByte(':')
|
||||
}
|
||||
}
|
||||
p.printValue(getField(v, i), verb, plus, depth+1)
|
||||
p.printValue(getField(v, i), verb, depth+1)
|
||||
}
|
||||
p.buf.WriteByte('}')
|
||||
case reflect.Interface:
|
||||
@ -935,7 +928,7 @@ BigSwitch:
|
||||
p.buf.Write(nilAngleBytes)
|
||||
}
|
||||
} else {
|
||||
wasString = p.printValue(value, verb, plus, depth+1)
|
||||
wasString = p.printValue(value, verb, depth+1)
|
||||
}
|
||||
case reflect.Array, reflect.Slice:
|
||||
// Byte slices are special:
|
||||
@ -980,7 +973,7 @@ BigSwitch:
|
||||
p.buf.WriteByte(' ')
|
||||
}
|
||||
}
|
||||
p.printValue(f.Index(i), verb, plus, depth+1)
|
||||
p.printValue(f.Index(i), verb, depth+1)
|
||||
}
|
||||
if p.fmt.sharpV {
|
||||
p.buf.WriteByte('}')
|
||||
@ -995,11 +988,15 @@ BigSwitch:
|
||||
switch a := f.Elem(); a.Kind() {
|
||||
case reflect.Array, reflect.Slice:
|
||||
p.buf.WriteByte('&')
|
||||
p.printValue(a, verb, plus, depth+1)
|
||||
p.printValue(a, verb, depth+1)
|
||||
break BigSwitch
|
||||
case reflect.Struct:
|
||||
p.buf.WriteByte('&')
|
||||
p.printValue(a, verb, plus, depth+1)
|
||||
p.printValue(a, verb, depth+1)
|
||||
break BigSwitch
|
||||
case reflect.Map:
|
||||
p.buf.WriteByte('&')
|
||||
p.printValue(a, verb, depth+1)
|
||||
break BigSwitch
|
||||
}
|
||||
}
|
||||
@ -1171,13 +1168,19 @@ func (p *pp) doPrintf(format string, a []interface{}) {
|
||||
arg := a[argNum]
|
||||
argNum++
|
||||
|
||||
if c == 'v' && p.fmt.sharp {
|
||||
// Go syntax. Set the flag in the fmt and clear the sharp flag.
|
||||
p.fmt.sharp = false
|
||||
p.fmt.sharpV = true
|
||||
if c == 'v' {
|
||||
if p.fmt.sharp {
|
||||
// Go syntax. Set the flag in the fmt and clear the sharp flag.
|
||||
p.fmt.sharp = false
|
||||
p.fmt.sharpV = true
|
||||
}
|
||||
if p.fmt.plus {
|
||||
// Struct-field syntax. Set the flag in the fmt and clear the plus flag.
|
||||
p.fmt.plus = false
|
||||
p.fmt.plusV = true
|
||||
}
|
||||
}
|
||||
plus := c == 'v' && p.fmt.plus
|
||||
p.printArg(arg, c, plus, 0)
|
||||
p.printArg(arg, c, 0)
|
||||
}
|
||||
|
||||
// Check for extra arguments unless the call accessed the arguments
|
||||
@ -1191,7 +1194,7 @@ func (p *pp) doPrintf(format string, a []interface{}) {
|
||||
p.buf.WriteString(reflect.TypeOf(arg).String())
|
||||
p.buf.WriteByte('=')
|
||||
}
|
||||
p.printArg(arg, 'v', false, 0)
|
||||
p.printArg(arg, 'v', 0)
|
||||
if argNum+1 < len(a) {
|
||||
p.buf.Write(commaSpaceBytes)
|
||||
}
|
||||
@ -1212,7 +1215,7 @@ func (p *pp) doPrint(a []interface{}, addspace, addnewline bool) {
|
||||
p.buf.WriteByte(' ')
|
||||
}
|
||||
}
|
||||
prevString = p.printArg(arg, 'v', false, 0)
|
||||
prevString = p.printArg(arg, 'v', 0)
|
||||
}
|
||||
if addnewline {
|
||||
p.buf.WriteByte('\n')
|
||||
|
@ -274,7 +274,8 @@ struct MStats
|
||||
bool debuggc;
|
||||
|
||||
// Statistics about allocation size classes.
|
||||
struct {
|
||||
|
||||
struct MStatsBySize {
|
||||
uint32 size;
|
||||
uint64 nmalloc;
|
||||
uint64 nfree;
|
||||
@ -283,6 +284,7 @@ struct MStats
|
||||
uint64 tinyallocs; // number of tiny allocations that didn't cause actual allocation; not exported to Go directly
|
||||
};
|
||||
|
||||
|
||||
#define mstats runtime·memstats
|
||||
extern MStats mstats;
|
||||
void runtime·updatememstats(GCStats *stats);
|
||||
@ -493,7 +495,7 @@ struct MHeap
|
||||
// the padding makes sure that the MCentrals are
|
||||
// spaced CacheLineSize bytes apart, so that each MCentral.lock
|
||||
// gets its own cache line.
|
||||
struct {
|
||||
struct MHeapCentral {
|
||||
MCentral mcentral;
|
||||
byte pad[CacheLineSize];
|
||||
} central[NumSizeClasses];
|
||||
|
@ -63,7 +63,7 @@ typedef struct Tos Tos;
|
||||
typedef intptr _Plink;
|
||||
|
||||
struct Tos {
|
||||
struct /* Per process profiling */
|
||||
struct TosProf /* Per process profiling */
|
||||
{
|
||||
_Plink *pp; /* known to be 0(ptr) */
|
||||
_Plink *next; /* known to be 4(ptr) */
|
||||
|
@ -2422,7 +2422,7 @@ runtime·mcount(void)
|
||||
return runtime·sched.mcount;
|
||||
}
|
||||
|
||||
static struct {
|
||||
static struct ProfState {
|
||||
uint32 lock;
|
||||
int32 hz;
|
||||
} prof;
|
||||
|
@ -177,6 +177,9 @@ func releaseSudog(s *sudog) {
|
||||
if s.elem != nil {
|
||||
gothrow("runtime: sudog with non-nil elem")
|
||||
}
|
||||
if s.selectdone != nil {
|
||||
gothrow("runtime: sudog with non-nil selectdone")
|
||||
}
|
||||
gp := getg()
|
||||
if gp.param != nil {
|
||||
gothrow("runtime: releaseSudog with non-nil gp.param")
|
||||
|
@ -385,11 +385,11 @@ struct M
|
||||
// these are here because they are too large to be on the stack
|
||||
// of low-level NOSPLIT functions.
|
||||
LibCall libcall;
|
||||
struct {
|
||||
struct MTs {
|
||||
int64 tv_sec;
|
||||
int64 tv_nsec;
|
||||
} ts;
|
||||
struct {
|
||||
struct MScratch {
|
||||
uintptr v[6];
|
||||
} scratch;
|
||||
#endif
|
||||
|
@ -379,6 +379,7 @@ loop:
|
||||
sglist = gp.waiting
|
||||
// Clear all elem before unlinking from gp.waiting.
|
||||
for sg1 := gp.waiting; sg1 != nil; sg1 = sg1.waitlink {
|
||||
sg1.selectdone = nil
|
||||
sg1.elem = nil
|
||||
}
|
||||
gp.waiting = nil
|
||||
|
@ -52,7 +52,7 @@ typedef uint16 Elf64_Section;
|
||||
typedef Elf64_Half Elf64_Versym;
|
||||
|
||||
|
||||
typedef struct
|
||||
typedef struct Elf64_Sym
|
||||
{
|
||||
Elf64_Word st_name;
|
||||
byte st_info;
|
||||
@ -62,7 +62,7 @@ typedef struct
|
||||
Elf64_Xword st_size;
|
||||
} Elf64_Sym;
|
||||
|
||||
typedef struct
|
||||
typedef struct Elf64_Verdef
|
||||
{
|
||||
Elf64_Half vd_version; /* Version revision */
|
||||
Elf64_Half vd_flags; /* Version information */
|
||||
@ -73,7 +73,7 @@ typedef struct
|
||||
Elf64_Word vd_next; /* Offset in bytes to next verdef entry */
|
||||
} Elf64_Verdef;
|
||||
|
||||
typedef struct
|
||||
typedef struct Elf64_Ehdr
|
||||
{
|
||||
byte e_ident[EI_NIDENT]; /* Magic number and other info */
|
||||
Elf64_Half e_type; /* Object file type */
|
||||
@ -91,7 +91,7 @@ typedef struct
|
||||
Elf64_Half e_shstrndx; /* Section header string table index */
|
||||
} Elf64_Ehdr;
|
||||
|
||||
typedef struct
|
||||
typedef struct Elf64_Phdr
|
||||
{
|
||||
Elf64_Word p_type; /* Segment type */
|
||||
Elf64_Word p_flags; /* Segment flags */
|
||||
@ -103,7 +103,7 @@ typedef struct
|
||||
Elf64_Xword p_align; /* Segment alignment */
|
||||
} Elf64_Phdr;
|
||||
|
||||
typedef struct
|
||||
typedef struct Elf64_Shdr
|
||||
{
|
||||
Elf64_Word sh_name; /* Section name (string tbl index) */
|
||||
Elf64_Word sh_type; /* Section type */
|
||||
@ -117,7 +117,7 @@ typedef struct
|
||||
Elf64_Xword sh_entsize; /* Entry size if section holds table */
|
||||
} Elf64_Shdr;
|
||||
|
||||
typedef struct
|
||||
typedef struct Elf64_Dyn
|
||||
{
|
||||
Elf64_Sxword d_tag; /* Dynamic entry type */
|
||||
union
|
||||
@ -127,13 +127,13 @@ typedef struct
|
||||
} d_un;
|
||||
} Elf64_Dyn;
|
||||
|
||||
typedef struct
|
||||
typedef struct Elf64_Verdaux
|
||||
{
|
||||
Elf64_Word vda_name; /* Version or dependency names */
|
||||
Elf64_Word vda_next; /* Offset in bytes to next verdaux entry */
|
||||
} Elf64_Verdaux;
|
||||
|
||||
typedef struct
|
||||
typedef struct Elf64_auxv_t
|
||||
{
|
||||
uint64 a_type; /* Entry type */
|
||||
union
|
||||
@ -143,13 +143,13 @@ typedef struct
|
||||
} Elf64_auxv_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
typedef struct symbol_key {
|
||||
byte* name;
|
||||
int32 sym_hash;
|
||||
void** var_ptr;
|
||||
} symbol_key;
|
||||
|
||||
typedef struct {
|
||||
typedef struct version_key {
|
||||
byte* version;
|
||||
int32 ver_hash;
|
||||
} version_key;
|
||||
|
@ -138,8 +138,6 @@ func (p *Param) StringTmpVarCode() string {
|
||||
// TmpVarCode returns source code for temp variable.
|
||||
func (p *Param) TmpVarCode() string {
|
||||
switch {
|
||||
case p.Type == "string":
|
||||
return p.StringTmpVarCode()
|
||||
case p.Type == "bool":
|
||||
return p.BoolTmpVarCode()
|
||||
case strings.HasPrefix(p.Type, "[]"):
|
||||
@ -149,19 +147,26 @@ func (p *Param) TmpVarCode() string {
|
||||
}
|
||||
}
|
||||
|
||||
// TmpVarHelperCode returns source code for helper's temp variable.
|
||||
func (p *Param) TmpVarHelperCode() string {
|
||||
if p.Type != "string" {
|
||||
return ""
|
||||
}
|
||||
return p.StringTmpVarCode()
|
||||
}
|
||||
|
||||
// SyscallArgList returns source code fragments representing p parameter
|
||||
// in syscall. Slices are translated into 2 syscall parameters: pointer to
|
||||
// the first element and length.
|
||||
func (p *Param) SyscallArgList() []string {
|
||||
t := p.HelperType()
|
||||
var s string
|
||||
switch {
|
||||
case p.Type[0] == '*':
|
||||
case t[0] == '*':
|
||||
s = fmt.Sprintf("unsafe.Pointer(%s)", p.Name)
|
||||
case p.Type == "string":
|
||||
s = fmt.Sprintf("unsafe.Pointer(%s)", p.tmpVar())
|
||||
case p.Type == "bool":
|
||||
case t == "bool":
|
||||
s = p.tmpVar()
|
||||
case strings.HasPrefix(p.Type, "[]"):
|
||||
case strings.HasPrefix(t, "[]"):
|
||||
return []string{
|
||||
fmt.Sprintf("uintptr(unsafe.Pointer(%s))", p.tmpVar()),
|
||||
fmt.Sprintf("uintptr(len(%s))", p.Name),
|
||||
@ -177,6 +182,14 @@ func (p *Param) IsError() bool {
|
||||
return p.Name == "err" && p.Type == "error"
|
||||
}
|
||||
|
||||
// HelperType returns type of parameter p used in helper function.
|
||||
func (p *Param) HelperType() string {
|
||||
if p.Type == "string" {
|
||||
return p.fn.StrconvType()
|
||||
}
|
||||
return p.Type
|
||||
}
|
||||
|
||||
// join concatenates parameters ps into a string with sep separator.
|
||||
// Each parameter is converted into string by applying fn to it
|
||||
// before conversion.
|
||||
@ -454,6 +467,11 @@ func (f *Fn) ParamList() string {
|
||||
return join(f.Params, func(p *Param) string { return p.Name + " " + p.Type }, ", ")
|
||||
}
|
||||
|
||||
// HelperParamList returns source code for helper function f parameters.
|
||||
func (f *Fn) HelperParamList() string {
|
||||
return join(f.Params, func(p *Param) string { return p.Name + " " + p.HelperType() }, ", ")
|
||||
}
|
||||
|
||||
// ParamPrintList returns source code of trace printing part correspondent
|
||||
// to syscall input parameters.
|
||||
func (f *Fn) ParamPrintList() string {
|
||||
@ -510,6 +528,19 @@ func (f *Fn) SyscallParamList() string {
|
||||
return strings.Join(a, ", ")
|
||||
}
|
||||
|
||||
// HelperCallParamList returns source code of call into function f helper.
|
||||
func (f *Fn) HelperCallParamList() string {
|
||||
a := make([]string, 0, len(f.Params))
|
||||
for _, p := range f.Params {
|
||||
s := p.Name
|
||||
if p.Type == "string" {
|
||||
s = p.tmpVar()
|
||||
}
|
||||
a = append(a, s)
|
||||
}
|
||||
return strings.Join(a, ", ")
|
||||
}
|
||||
|
||||
// IsUTF16 is true, if f is W (utf16) function. It is false
|
||||
// for all A (ascii) functions.
|
||||
func (f *Fn) IsUTF16() bool {
|
||||
@ -533,6 +564,25 @@ func (f *Fn) StrconvType() string {
|
||||
return "*byte"
|
||||
}
|
||||
|
||||
// HasStringParam is true, if f has at least one string parameter.
|
||||
// Otherwise it is false.
|
||||
func (f *Fn) HasStringParam() bool {
|
||||
for _, p := range f.Params {
|
||||
if p.Type == "string" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// HelperName returns name of function f helper.
|
||||
func (f *Fn) HelperName() string {
|
||||
if !f.HasStringParam() {
|
||||
return f.Name
|
||||
}
|
||||
return "_" + f.Name
|
||||
}
|
||||
|
||||
// Source files and functions.
|
||||
type Source struct {
|
||||
Funcs []*Fn
|
||||
@ -666,7 +716,7 @@ import "syscall"{{end}}
|
||||
var (
|
||||
{{template "dlls" .}}
|
||||
{{template "funcnames" .}})
|
||||
{{range .Funcs}}{{template "funcbody" .}}{{end}}
|
||||
{{range .Funcs}}{{if .HasStringParam}}{{template "helperbody" .}}{{end}}{{template "funcbody" .}}{{end}}
|
||||
{{end}}
|
||||
|
||||
{{/* help functions */}}
|
||||
@ -677,16 +727,27 @@ var (
|
||||
{{define "funcnames"}}{{range .Funcs}} proc{{.DLLFuncName}} = mod{{.DLLName}}.NewProc("{{.DLLFuncName}}")
|
||||
{{end}}{{end}}
|
||||
|
||||
{{define "helperbody"}}
|
||||
func {{.Name}}({{.ParamList}}) {{template "results" .}}{
|
||||
{{template "helpertmpvars" .}} return {{.HelperName}}({{.HelperCallParamList}})
|
||||
}
|
||||
{{end}}
|
||||
|
||||
{{define "funcbody"}}
|
||||
func {{.Name}}({{.ParamList}}) {{if .Rets.List}}{{.Rets.List}} {{end}}{
|
||||
func {{.HelperName}}({{.HelperParamList}}) {{template "results" .}}{
|
||||
{{template "tmpvars" .}} {{template "syscall" .}}
|
||||
{{template "seterror" .}}{{template "printtrace" .}} return
|
||||
}
|
||||
{{end}}
|
||||
|
||||
{{define "helpertmpvars"}}{{range .Params}}{{if .TmpVarHelperCode}} {{.TmpVarHelperCode}}
|
||||
{{end}}{{end}}{{end}}
|
||||
|
||||
{{define "tmpvars"}}{{range .Params}}{{if .TmpVarCode}} {{.TmpVarCode}}
|
||||
{{end}}{{end}}{{end}}
|
||||
|
||||
{{define "results"}}{{if .Rets.List}}{{.Rets.List}} {{end}}{{end}}
|
||||
|
||||
{{define "syscall"}}{{.Rets.SetReturnValuesCode}}{{.Syscall}}(proc{{.DLLFuncName}}.Addr(), {{.ParamCount}}, {{.SyscallParamList}}){{end}}
|
||||
|
||||
{{define "seterror"}}{{if .Rets.SetErrorCode}} {{.Rets.SetErrorCode}}
|
||||
|
@ -176,7 +176,11 @@ func LoadLibrary(libname string) (handle Handle, err error) {
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
r0, _, e1 := Syscall(procLoadLibraryW.Addr(), 1, uintptr(unsafe.Pointer(_p0)), 0, 0)
|
||||
return _LoadLibrary(_p0)
|
||||
}
|
||||
|
||||
func _LoadLibrary(libname *uint16) (handle Handle, err error) {
|
||||
r0, _, e1 := Syscall(procLoadLibraryW.Addr(), 1, uintptr(unsafe.Pointer(libname)), 0, 0)
|
||||
handle = Handle(r0)
|
||||
if handle == 0 {
|
||||
if e1 != 0 {
|
||||
@ -206,7 +210,11 @@ func GetProcAddress(module Handle, procname string) (proc uintptr, err error) {
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
r0, _, e1 := Syscall(procGetProcAddress.Addr(), 2, uintptr(module), uintptr(unsafe.Pointer(_p0)), 0)
|
||||
return _GetProcAddress(module, _p0)
|
||||
}
|
||||
|
||||
func _GetProcAddress(module Handle, procname *byte) (proc uintptr, err error) {
|
||||
r0, _, e1 := Syscall(procGetProcAddress.Addr(), 2, uintptr(module), uintptr(unsafe.Pointer(procname)), 0)
|
||||
proc = uintptr(r0)
|
||||
if proc == 0 {
|
||||
if e1 != 0 {
|
||||
@ -1558,7 +1566,11 @@ func GetHostByName(name string) (h *Hostent, err error) {
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
r0, _, e1 := Syscall(procgethostbyname.Addr(), 1, uintptr(unsafe.Pointer(_p0)), 0, 0)
|
||||
return _GetHostByName(_p0)
|
||||
}
|
||||
|
||||
func _GetHostByName(name *byte) (h *Hostent, err error) {
|
||||
r0, _, e1 := Syscall(procgethostbyname.Addr(), 1, uintptr(unsafe.Pointer(name)), 0, 0)
|
||||
h = (*Hostent)(unsafe.Pointer(r0))
|
||||
if h == nil {
|
||||
if e1 != 0 {
|
||||
@ -1581,7 +1593,11 @@ func GetServByName(name string, proto string) (s *Servent, err error) {
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
r0, _, e1 := Syscall(procgetservbyname.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
|
||||
return _GetServByName(_p0, _p1)
|
||||
}
|
||||
|
||||
func _GetServByName(name *byte, proto *byte) (s *Servent, err error) {
|
||||
r0, _, e1 := Syscall(procgetservbyname.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(proto)), 0)
|
||||
s = (*Servent)(unsafe.Pointer(r0))
|
||||
if s == nil {
|
||||
if e1 != 0 {
|
||||
@ -1605,7 +1621,11 @@ func GetProtoByName(name string) (p *Protoent, err error) {
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
r0, _, e1 := Syscall(procgetprotobyname.Addr(), 1, uintptr(unsafe.Pointer(_p0)), 0, 0)
|
||||
return _GetProtoByName(_p0)
|
||||
}
|
||||
|
||||
func _GetProtoByName(name *byte) (p *Protoent, err error) {
|
||||
r0, _, e1 := Syscall(procgetprotobyname.Addr(), 1, uintptr(unsafe.Pointer(name)), 0, 0)
|
||||
p = (*Protoent)(unsafe.Pointer(r0))
|
||||
if p == nil {
|
||||
if e1 != 0 {
|
||||
@ -1623,7 +1643,11 @@ func DnsQuery(name string, qtype uint16, options uint32, extra *byte, qrs **DNSR
|
||||
if status != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := Syscall6(procDnsQuery_W.Addr(), 6, uintptr(unsafe.Pointer(_p0)), uintptr(qtype), uintptr(options), uintptr(unsafe.Pointer(extra)), uintptr(unsafe.Pointer(qrs)), uintptr(unsafe.Pointer(pr)))
|
||||
return _DnsQuery(_p0, qtype, options, extra, qrs, pr)
|
||||
}
|
||||
|
||||
func _DnsQuery(name *uint16, qtype uint16, options uint32, extra *byte, qrs **DNSRecord, pr *byte) (status error) {
|
||||
r0, _, _ := Syscall6(procDnsQuery_W.Addr(), 6, uintptr(unsafe.Pointer(name)), uintptr(qtype), uintptr(options), uintptr(unsafe.Pointer(extra)), uintptr(unsafe.Pointer(qrs)), uintptr(unsafe.Pointer(pr)))
|
||||
if r0 != 0 {
|
||||
status = Errno(r0)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user