mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.boringcrypto] all: merge master into dev.boringcrypto
Conflicts due to simple variable renames (d <-> d0):
src/crypto/sha1/sha1.go
src/crypto/sha256/sha256.go
src/crypto/sha512/sha512.go
Change-Id: I437df180a527fb3ec8b47927ee71960d5d200b76
This commit is contained in:
commit
a3f9ce3313
1997 changed files with 211360 additions and 117222 deletions
26
.github/PULL_REQUEST_TEMPLATE
vendored
26
.github/PULL_REQUEST_TEMPLATE
vendored
|
|
@ -1,7 +1,25 @@
|
||||||
Please do not send pull requests to the golang/* repositories.
|
This PR will be imported into Gerrit with the title and first
|
||||||
|
comment (this text) used to generate the subject and body of
|
||||||
|
the Gerrit change.
|
||||||
|
|
||||||
We do, however, take contributions gladly.
|
**Please ensure you adhere to every item in this list.**
|
||||||
|
|
||||||
See https://golang.org/doc/contribute.html
|
More info can be found at https://github.com/golang/go/wiki/CommitMessage
|
||||||
|
|
||||||
Thanks!
|
+ The PR title is formatted as follows: `net/http: frob the quux before blarfing`
|
||||||
|
+ The package name goes before the colon
|
||||||
|
+ The part after the colon uses the verb tense + phrase that completes the blank in,
|
||||||
|
"This change modifies Go to ___________"
|
||||||
|
+ Lowercase verb after the colon
|
||||||
|
+ No trailing period
|
||||||
|
+ Keep the title as short as possible. ideally under 76 characters or shorter
|
||||||
|
+ No Markdown
|
||||||
|
+ The first PR comment (this one) is wrapped at 76 characters, unless it's
|
||||||
|
really needed (ASCII art, table, or long link)
|
||||||
|
+ If there is a corresponding issue, add either `Fixes #1234` or `Updates #1234`
|
||||||
|
(the latter if this is not a complete fix) to this comment
|
||||||
|
+ If referring to a repo other than `golang/go` you can use the
|
||||||
|
`owner/repo#issue_number` syntax: `Fixes golang/tools#1234`
|
||||||
|
+ We do not use Signed-off-by lines in Go. Please don't add them.
|
||||||
|
Our Gerrit server & GitHub bots enforce CLA compliance instead.
|
||||||
|
+ Delete these instructions once you have read and applied them
|
||||||
|
|
|
||||||
159
AUTHORS
159
AUTHORS
|
|
@ -18,13 +18,18 @@ Abe Haskins <abeisgreat@abeisgreat.com>
|
||||||
Abhinav Gupta <abhinav.g90@gmail.com>
|
Abhinav Gupta <abhinav.g90@gmail.com>
|
||||||
Adam Eijdenberg <adam@continusec.com>
|
Adam Eijdenberg <adam@continusec.com>
|
||||||
Adam Kisala <adam.kisala@gmail.com>
|
Adam Kisala <adam.kisala@gmail.com>
|
||||||
|
Adam Thomason <athomason@gmail.com>
|
||||||
Aditya Mukerjee <dev@chimeracoder.net>
|
Aditya Mukerjee <dev@chimeracoder.net>
|
||||||
|
Adrian Hesketh <adrianhesketh@hushmail.com>
|
||||||
Adrian Nos <nos.adrian@gmail.com>
|
Adrian Nos <nos.adrian@gmail.com>
|
||||||
Adrian O'Grady <elpollouk@gmail.com>
|
Adrian O'Grady <elpollouk@gmail.com>
|
||||||
Adrien Bustany <adrien-xx-google@bustany.org>
|
Adrien Bustany <adrien-xx-google@bustany.org>
|
||||||
Aécio Júnior <aeciodantasjunior@gmail.com>
|
Aécio Júnior <aeciodantasjunior@gmail.com>
|
||||||
|
Aeneas Rekkas (arekkas) <aeneas@ory.am>
|
||||||
|
Afanasev Stanislav <phpprogger@gmail.com>
|
||||||
Agis Anastasopoulos <agis.anast@gmail.com>
|
Agis Anastasopoulos <agis.anast@gmail.com>
|
||||||
Ahmed Waheed Moanes <oneofone@gmail.com>
|
Agniva De Sarker <agnivade@yahoo.co.in>
|
||||||
|
Ahmed Wahed <oneofone@gmail.com>
|
||||||
Ahmy Yulrizka <yulrizka@gmail.com>
|
Ahmy Yulrizka <yulrizka@gmail.com>
|
||||||
Aiden Scandella <ai@uber.com>
|
Aiden Scandella <ai@uber.com>
|
||||||
Ainar Garipov <gugl.zadolbal@gmail.com>
|
Ainar Garipov <gugl.zadolbal@gmail.com>
|
||||||
|
|
@ -60,6 +65,7 @@ Alexander Menzhinsky <amenzhinsky@gmail.com>
|
||||||
Alexander Morozov <lk4d4math@gmail.com>
|
Alexander Morozov <lk4d4math@gmail.com>
|
||||||
Alexander Neumann <alexander@bumpern.de>
|
Alexander Neumann <alexander@bumpern.de>
|
||||||
Alexander Orlov <alexander.orlov@loxal.net>
|
Alexander Orlov <alexander.orlov@loxal.net>
|
||||||
|
Alexander Pantyukhin <apantykhin@gmail.com>
|
||||||
Alexander Reece <awreece@gmail.com>
|
Alexander Reece <awreece@gmail.com>
|
||||||
Alexander Surma <surma@surmair.de>
|
Alexander Surma <surma@surmair.de>
|
||||||
Alexander Zhavnerchik <alex.vizor@gmail.com>
|
Alexander Zhavnerchik <alex.vizor@gmail.com>
|
||||||
|
|
@ -67,6 +73,7 @@ Alexander Zolotov <goldifit@gmail.com>
|
||||||
Alexandre Cesaro <alexandre.cesaro@gmail.com>
|
Alexandre Cesaro <alexandre.cesaro@gmail.com>
|
||||||
Alexandre Fiori <fiorix@gmail.com>
|
Alexandre Fiori <fiorix@gmail.com>
|
||||||
Alexandre Normand <alexandre.normand@gmail.com>
|
Alexandre Normand <alexandre.normand@gmail.com>
|
||||||
|
Alexandre Parentea <aubonbeurre@gmail.com>
|
||||||
Alexei Sholik <alcosholik@gmail.com>
|
Alexei Sholik <alcosholik@gmail.com>
|
||||||
Alexey Borzenkov <snaury@gmail.com>
|
Alexey Borzenkov <snaury@gmail.com>
|
||||||
Alexey Neganov <neganovalexey@gmail.com>
|
Alexey Neganov <neganovalexey@gmail.com>
|
||||||
|
|
@ -76,9 +83,11 @@ Aliaksandr Valialkin <valyala@gmail.com>
|
||||||
Alif Rachmawadi <subosito@gmail.com>
|
Alif Rachmawadi <subosito@gmail.com>
|
||||||
Allan Simon <allan.simon@supinfo.com>
|
Allan Simon <allan.simon@supinfo.com>
|
||||||
Alok Menghrajani <alok.menghrajani@gmail.com>
|
Alok Menghrajani <alok.menghrajani@gmail.com>
|
||||||
|
Aman Gupta <aman@tmm1.net>
|
||||||
Amazon.com, Inc
|
Amazon.com, Inc
|
||||||
Amir Mohammad Saied <amir@gluegadget.com>
|
Amir Mohammad Saied <amir@gluegadget.com>
|
||||||
Amrut Joshi <amrut.joshi@gmail.com>
|
Amrut Joshi <amrut.joshi@gmail.com>
|
||||||
|
Anand K. Mistry <anand@mistry.ninja>
|
||||||
Anders Pearson <anders@columbia.edu>
|
Anders Pearson <anders@columbia.edu>
|
||||||
André Carvalho <asantostc@gmail.com>
|
André Carvalho <asantostc@gmail.com>
|
||||||
Andre Nathan <andrenth@gmail.com>
|
Andre Nathan <andrenth@gmail.com>
|
||||||
|
|
@ -104,7 +113,10 @@ Andrew Wilkins <axwalk@gmail.com>
|
||||||
Andrew Williams <williams.andrew@gmail.com>
|
Andrew Williams <williams.andrew@gmail.com>
|
||||||
Andrey Mirtchovski <mirtchovski@gmail.com>
|
Andrey Mirtchovski <mirtchovski@gmail.com>
|
||||||
Andrey Petrov <andrey.petrov@shazow.net>
|
Andrey Petrov <andrey.petrov@shazow.net>
|
||||||
|
Andrii Soldatenko <andrii.soldatenko@gmail.com>
|
||||||
|
Andrii Soluk <isoluchok@gmail.com>
|
||||||
Andriy Lytvynov <lytvynov.a.v@gmail.com>
|
Andriy Lytvynov <lytvynov.a.v@gmail.com>
|
||||||
|
Andrzej Żeżel <andrii.zhezhel@gmail.com>
|
||||||
Andy Balholm <andy@balholm.com>
|
Andy Balholm <andy@balholm.com>
|
||||||
Andy Davis <andy@bigandian.com>
|
Andy Davis <andy@bigandian.com>
|
||||||
Andy Finkenstadt <afinkenstadt@zynga.com>
|
Andy Finkenstadt <afinkenstadt@zynga.com>
|
||||||
|
|
@ -115,9 +127,11 @@ Angelo Bulfone <mbulfone@gmail.com>
|
||||||
Anh Hai Trinh <anh.hai.trinh@gmail.com>
|
Anh Hai Trinh <anh.hai.trinh@gmail.com>
|
||||||
Anmol Sethi <anmol@aubble.com>
|
Anmol Sethi <anmol@aubble.com>
|
||||||
Anschel Schaffer-Cohen <anschelsc@gmail.com>
|
Anschel Schaffer-Cohen <anschelsc@gmail.com>
|
||||||
|
Anthony Alves <cvballa3g0@gmail.com>
|
||||||
Anthony Canino <anthony.canino1@gmail.com>
|
Anthony Canino <anthony.canino1@gmail.com>
|
||||||
Anthony Eufemio <anthony.eufemio@gmail.com>
|
Anthony Eufemio <anthony.eufemio@gmail.com>
|
||||||
Anthony Martin <ality@pbrane.org>
|
Anthony Martin <ality@pbrane.org>
|
||||||
|
Anthony Sottile <asottile@umich.edu>
|
||||||
Anthony Starks <ajstarks@gmail.com>
|
Anthony Starks <ajstarks@gmail.com>
|
||||||
Anthony Voutas <voutasaurus@gmail.com>
|
Anthony Voutas <voutasaurus@gmail.com>
|
||||||
Anthony Woods <awoods@raintank.io>
|
Anthony Woods <awoods@raintank.io>
|
||||||
|
|
@ -128,6 +142,7 @@ Apisak Darakananda <pongad@gmail.com>
|
||||||
Apsalar
|
Apsalar
|
||||||
Aram Hăvărneanu <aram@mgk.ro>
|
Aram Hăvărneanu <aram@mgk.ro>
|
||||||
Areski Belaid <areski@gmail.com>
|
Areski Belaid <areski@gmail.com>
|
||||||
|
Ariel Mashraki <ariel@mashraki.co.il>
|
||||||
Arlo Breault <arlolra@gmail.com>
|
Arlo Breault <arlolra@gmail.com>
|
||||||
ARM Ltd.
|
ARM Ltd.
|
||||||
Arnaud Ysmal <arnaud.ysmal@gmail.com>
|
Arnaud Ysmal <arnaud.ysmal@gmail.com>
|
||||||
|
|
@ -143,12 +158,14 @@ Augusto Roman <aroman@gmail.com>
|
||||||
Aulus Egnatius Varialus <varialus@gmail.com>
|
Aulus Egnatius Varialus <varialus@gmail.com>
|
||||||
awaw fumin <awawfumin@gmail.com>
|
awaw fumin <awawfumin@gmail.com>
|
||||||
Awn Umar <awn@cryptolosophy.io>
|
Awn Umar <awn@cryptolosophy.io>
|
||||||
|
Axel Wagner <axel.wagner.hh@googlemail.com>
|
||||||
Ayanamist Yang <ayanamist@gmail.com>
|
Ayanamist Yang <ayanamist@gmail.com>
|
||||||
Aymerick Jéhanne <aymerick@jehanne.org>
|
Aymerick Jéhanne <aymerick@jehanne.org>
|
||||||
Baiju Muthukadan <baiju.m.mail@gmail.com>
|
Baiju Muthukadan <baiju.m.mail@gmail.com>
|
||||||
Bartosz Grzybowski <melkorm@gmail.com>
|
Bartosz Grzybowski <melkorm@gmail.com>
|
||||||
Bastian Ike <bastian.ike@gmail.com>
|
Bastian Ike <bastian.ike@gmail.com>
|
||||||
Ben Burkert <ben@benburkert.com>
|
Ben Burkert <ben@benburkert.com>
|
||||||
|
Ben Haines <bhainesva@gmail.com>
|
||||||
Ben Lubar <ben.lubar@gmail.com>
|
Ben Lubar <ben.lubar@gmail.com>
|
||||||
Ben Olive <sionide21@gmail.com>
|
Ben Olive <sionide21@gmail.com>
|
||||||
Ben Shi <powerman1st@163.com>
|
Ben Shi <powerman1st@163.com>
|
||||||
|
|
@ -159,26 +176,33 @@ Berengar Lehr <berengar.lehr@gmx.de>
|
||||||
Billie Harold Cleek <bhcleek@gmail.com>
|
Billie Harold Cleek <bhcleek@gmail.com>
|
||||||
Bjorn Tillenius <bjorn@tillenius.me>
|
Bjorn Tillenius <bjorn@tillenius.me>
|
||||||
Bjorn Tipling <bjorn.tipling@gmail.com>
|
Bjorn Tipling <bjorn.tipling@gmail.com>
|
||||||
|
Blain Smith <rebelgeek@blainsmith.com>
|
||||||
Blake Gentry <blakesgentry@gmail.com>
|
Blake Gentry <blakesgentry@gmail.com>
|
||||||
|
Blake Mesdag <blakemesdag@gmail.com>
|
||||||
Blake Mizerany <blake.mizerany@gmail.com>
|
Blake Mizerany <blake.mizerany@gmail.com>
|
||||||
Blixt <me@blixt.nyc>
|
Blixt <me@blixt.nyc>
|
||||||
Bobby Powers <bobbypowers@gmail.com>
|
Bobby Powers <bobbypowers@gmail.com>
|
||||||
Bolt
|
Bolt
|
||||||
|
Borja Clemente <borja.clemente@gmail.com>
|
||||||
|
Brad Burch <brad.burch@gmail.com>
|
||||||
Brady Catherman <brady@gmail.com>
|
Brady Catherman <brady@gmail.com>
|
||||||
Brady Sullivan <brady@bsull.com>
|
Brady Sullivan <brady@bsull.com>
|
||||||
Brendan Daniel Tracey <tracey.brendan@gmail.com>
|
Brendan Daniel Tracey <tracey.brendan@gmail.com>
|
||||||
Brett Cannon <bcannon@gmail.com>
|
Brett Cannon <bcannon@gmail.com>
|
||||||
|
Brett Merrill <brett.j.merrill94@gmail.com>
|
||||||
Brian Dellisanti <briandellisanti@gmail.com>
|
Brian Dellisanti <briandellisanti@gmail.com>
|
||||||
Brian Downs <brian.downs@gmail.com>
|
Brian Downs <brian.downs@gmail.com>
|
||||||
Brian G. Merrell <bgmerrell@gmail.com>
|
Brian G. Merrell <bgmerrell@gmail.com>
|
||||||
Brian Gitonga Marete <marete@toshnix.com> <bgmarete@gmail.com>
|
Brian Gitonga Marete <marete@toshnix.com> <bgmarete@gmail.com>
|
||||||
Brian Kennedy <btkennedy@gmail.com>
|
Brian Kennedy <btkennedy@gmail.com>
|
||||||
|
Brian Kessler <brian.m.kessler@gmail.com>
|
||||||
Brian Ketelsen <bketelsen@gmail.com>
|
Brian Ketelsen <bketelsen@gmail.com>
|
||||||
Brian Smith <ohohvi@gmail.com>
|
Brian Smith <ohohvi@gmail.com>
|
||||||
Brian Starke <brian.starke@gmail.com>
|
Brian Starke <brian.starke@gmail.com>
|
||||||
Bryan Alexander <Kozical@msn.com>
|
Bryan Alexander <Kozical@msn.com>
|
||||||
Bryan Ford <brynosaurus@gmail.com>
|
Bryan Ford <brynosaurus@gmail.com>
|
||||||
Bulat Gaifullin <gaifullinbf@gmail.com>
|
Bulat Gaifullin <gaifullinbf@gmail.com>
|
||||||
|
Burak Guven <bguven@gmail.com>
|
||||||
Caine Tighe <arctanofyourface@gmail.com>
|
Caine Tighe <arctanofyourface@gmail.com>
|
||||||
Caleb Spare <cespare@gmail.com>
|
Caleb Spare <cespare@gmail.com>
|
||||||
Carl Chatfield <carlchatfield@gmail.com>
|
Carl Chatfield <carlchatfield@gmail.com>
|
||||||
|
|
@ -193,9 +217,12 @@ Case Nelson <case.nelson@gmail.com>
|
||||||
Casey Marshall <casey.marshall@gmail.com>
|
Casey Marshall <casey.marshall@gmail.com>
|
||||||
Cezar Sá Espinola <cezarsa@gmail.com>
|
Cezar Sá Espinola <cezarsa@gmail.com>
|
||||||
ChaiShushan <chaishushan@gmail.com>
|
ChaiShushan <chaishushan@gmail.com>
|
||||||
|
Charles Fenwick Elliott <Charles@FenwickElliott.io>
|
||||||
Charles L. Dorian <cldorian@gmail.com>
|
Charles L. Dorian <cldorian@gmail.com>
|
||||||
Charles Lee <zombie.fml@gmail.com>
|
Charles Lee <zombie.fml@gmail.com>
|
||||||
Chew Choon Keat <choonkeat@gmail.com>
|
Chew Choon Keat <choonkeat@gmail.com>
|
||||||
|
Cholerae Hu <choleraehyq@gmail.com>
|
||||||
|
Chris Ball <chris@printf.net>
|
||||||
Chris Biscardi <chris@christopherbiscardi.com>
|
Chris Biscardi <chris@christopherbiscardi.com>
|
||||||
Chris Dollin <ehog.hedge@gmail.com>
|
Chris Dollin <ehog.hedge@gmail.com>
|
||||||
Chris Farmiloe <chrisfarms@gmail.com>
|
Chris Farmiloe <chrisfarms@gmail.com>
|
||||||
|
|
@ -207,6 +234,7 @@ Chris Lennert <calennert@gmail.com>
|
||||||
Chris McGee <sirnewton_01@yahoo.ca> <newton688@gmail.com>
|
Chris McGee <sirnewton_01@yahoo.ca> <newton688@gmail.com>
|
||||||
Chris Roche <rodaine@gmail.com>
|
Chris Roche <rodaine@gmail.com>
|
||||||
Chris Stockton <chrisstocktonaz@gmail.com>
|
Chris Stockton <chrisstocktonaz@gmail.com>
|
||||||
|
Christian Alexander <christian@linux.com>
|
||||||
Christian Couder <chriscool@tuxfamily.org>
|
Christian Couder <chriscool@tuxfamily.org>
|
||||||
Christian Himpel <chressie@googlemail.com>
|
Christian Himpel <chressie@googlemail.com>
|
||||||
Christine Hansmann <chhansmann@gmail.com>
|
Christine Hansmann <chhansmann@gmail.com>
|
||||||
|
|
@ -214,10 +242,12 @@ Christoffer Buchholz <christoffer.buchholz@gmail.com>
|
||||||
Christoph Hack <christoph@tux21b.org>
|
Christoph Hack <christoph@tux21b.org>
|
||||||
Christopher Cahoon <chris.cahoon@gmail.com>
|
Christopher Cahoon <chris.cahoon@gmail.com>
|
||||||
Christopher Guiney <chris@guiney.net>
|
Christopher Guiney <chris@guiney.net>
|
||||||
|
Christopher Henderson <chris@chenderson.org>
|
||||||
Christopher Nelson <nadiasvertex@gmail.com>
|
Christopher Nelson <nadiasvertex@gmail.com>
|
||||||
Christopher Nielsen <m4dh4tt3r@gmail.com>
|
Christopher Nielsen <m4dh4tt3r@gmail.com>
|
||||||
Christopher Redden <christopher.redden@gmail.com>
|
Christopher Redden <christopher.redden@gmail.com>
|
||||||
Christopher Wedgwood <cw@f00f.org>
|
Christopher Wedgwood <cw@f00f.org>
|
||||||
|
Christos Zoulas <christos@zoulas.com> <zoulasc@gmail.com>
|
||||||
CL Sung <clsung@gmail.com> <cl_sung@htc.com>
|
CL Sung <clsung@gmail.com> <cl_sung@htc.com>
|
||||||
Clement Skau <clementskau@gmail.com>
|
Clement Skau <clementskau@gmail.com>
|
||||||
CloudFlare Inc.
|
CloudFlare Inc.
|
||||||
|
|
@ -251,6 +281,8 @@ Daniel Skinner <daniel@dasa.cc>
|
||||||
Daniel Speichert <daniel@speichert.pl>
|
Daniel Speichert <daniel@speichert.pl>
|
||||||
Daniel Theophanes <kardianos@gmail.com>
|
Daniel Theophanes <kardianos@gmail.com>
|
||||||
Daniel Upton <daniel@floppy.co>
|
Daniel Upton <daniel@floppy.co>
|
||||||
|
Daniela Petruzalek <daniela.petruzalek@gmail.com>
|
||||||
|
Danny Rosseau <daniel.rosseau@gmail.com>
|
||||||
Darren Elwood <darren@textnode.com>
|
Darren Elwood <darren@textnode.com>
|
||||||
Datong Sun <dndx@idndx.com>
|
Datong Sun <dndx@idndx.com>
|
||||||
Dave Cheney <dave@cheney.net>
|
Dave Cheney <dave@cheney.net>
|
||||||
|
|
@ -272,6 +304,7 @@ David Thomas <davidthomas426@gmail.com>
|
||||||
David Titarenco <david.titarenco@gmail.com>
|
David Titarenco <david.titarenco@gmail.com>
|
||||||
David Volquartz Lebech <david@lebech.info>
|
David Volquartz Lebech <david@lebech.info>
|
||||||
Davies Liu <davies.liu@gmail.com>
|
Davies Liu <davies.liu@gmail.com>
|
||||||
|
Davor Kapsa <davor.kapsa@gmail.com>
|
||||||
Dean Prichard <dean.prichard@gmail.com>
|
Dean Prichard <dean.prichard@gmail.com>
|
||||||
Deepak Jois <deepak.jois@gmail.com>
|
Deepak Jois <deepak.jois@gmail.com>
|
||||||
Denis Bernard <db047h@gmail.com>
|
Denis Bernard <db047h@gmail.com>
|
||||||
|
|
@ -308,15 +341,19 @@ Dustin Sallings <dsallings@gmail.com>
|
||||||
Dustin Shields-Cloues <dcloues@gmail.com>
|
Dustin Shields-Cloues <dcloues@gmail.com>
|
||||||
Dvir Volk <dvir@everything.me> <dvirsky@gmail.com>
|
Dvir Volk <dvir@everything.me> <dvirsky@gmail.com>
|
||||||
Dylan Waits <dylan@waits.io>
|
Dylan Waits <dylan@waits.io>
|
||||||
|
Edan Bedrik <3d4nb3@gmail.com>
|
||||||
Eden Li <eden.li@gmail.com>
|
Eden Li <eden.li@gmail.com>
|
||||||
Edward Muller <edwardam@interlix.com>
|
Edward Muller <edwardam@interlix.com>
|
||||||
Egon Elbre <egonelbre@gmail.com>
|
Egon Elbre <egonelbre@gmail.com>
|
||||||
Ehren Kret <ehren.kret@gmail.com>
|
Ehren Kret <ehren.kret@gmail.com>
|
||||||
Eitan Adler <lists@eitanadler.com>
|
Eitan Adler <lists@eitanadler.com>
|
||||||
Eivind Uggedal <eivind@uggedal.com>
|
Eivind Uggedal <eivind@uggedal.com>
|
||||||
|
Elbert Fliek <efliek@gmail.com>
|
||||||
|
Elena Grahovac <elena@grahovac.me>
|
||||||
Elias Naur <elias.naur@gmail.com>
|
Elias Naur <elias.naur@gmail.com>
|
||||||
Elliot Morrison-Reed <elliotmr@gmail.com>
|
Elliot Morrison-Reed <elliotmr@gmail.com>
|
||||||
Emil Hessman <c.emil.hessman@gmail.com> <emil@hessman.se>
|
Emerson Lin <linyintor@gmail.com>
|
||||||
|
Emil Hessman <emil@hessman.se>
|
||||||
Emilien Kenler <hello@emilienkenler.com>
|
Emilien Kenler <hello@emilienkenler.com>
|
||||||
Emmanuel Odeke <emm.odeke@gmail.com> <odeke@ualberta.ca>
|
Emmanuel Odeke <emm.odeke@gmail.com> <odeke@ualberta.ca>
|
||||||
Empirical Interfaces Inc.
|
Empirical Interfaces Inc.
|
||||||
|
|
@ -326,6 +363,7 @@ Eric Clark <zerohp@gmail.com>
|
||||||
Eric Engestrom <eric@engestrom.ch>
|
Eric Engestrom <eric@engestrom.ch>
|
||||||
Eric Lagergren <ericscottlagergren@gmail.com>
|
Eric Lagergren <ericscottlagergren@gmail.com>
|
||||||
Eric Milliken <emilliken@gmail.com>
|
Eric Milliken <emilliken@gmail.com>
|
||||||
|
Eric Rescorla <ekr@rtfm.com>
|
||||||
Eric Roshan-Eisner <eric.d.eisner@gmail.com>
|
Eric Roshan-Eisner <eric.d.eisner@gmail.com>
|
||||||
Erik Aigner <aigner.erik@gmail.com>
|
Erik Aigner <aigner.erik@gmail.com>
|
||||||
Erik Dubbelboer <erik@dubbelboer.com>
|
Erik Dubbelboer <erik@dubbelboer.com>
|
||||||
|
|
@ -335,6 +373,7 @@ Ernest Chiang <ernest_chiang@htc.com>
|
||||||
Esko Luontola <esko.luontola@gmail.com>
|
Esko Luontola <esko.luontola@gmail.com>
|
||||||
Euan Kemp <euank@euank.com>
|
Euan Kemp <euank@euank.com>
|
||||||
Evan Hicks <evan.hicks2@gmail.com>
|
Evan Hicks <evan.hicks2@gmail.com>
|
||||||
|
Evan Jones <ej@evanjones.ca>
|
||||||
Evan Phoenix <evan@phx.io>
|
Evan Phoenix <evan@phx.io>
|
||||||
Evan Shaw <chickencha@gmail.com>
|
Evan Shaw <chickencha@gmail.com>
|
||||||
Evgeniy Polyakov <zbr@ioremap.net>
|
Evgeniy Polyakov <zbr@ioremap.net>
|
||||||
|
|
@ -363,6 +402,8 @@ Ford Hurley <ford.hurley@gmail.com>
|
||||||
Francisco Claude <fclaude@recoded.cl>
|
Francisco Claude <fclaude@recoded.cl>
|
||||||
Francisco Rojas <francisco.rojas.gallegos@gmail.com>
|
Francisco Rojas <francisco.rojas.gallegos@gmail.com>
|
||||||
Francisco Souza <franciscossouza@gmail.com>
|
Francisco Souza <franciscossouza@gmail.com>
|
||||||
|
Frank Somers <fsomers@arista.com>
|
||||||
|
Frederic Guillot <frederic.guillot@gmail.com>
|
||||||
Frederick Kelly Mayle III <frederickmayle@gmail.com>
|
Frederick Kelly Mayle III <frederickmayle@gmail.com>
|
||||||
Fredrik Enestad <fredrik.enestad@soundtrackyourbrand.com>
|
Fredrik Enestad <fredrik.enestad@soundtrackyourbrand.com>
|
||||||
Fredrik Forsmo <fredrik.forsmo@gmail.com>
|
Fredrik Forsmo <fredrik.forsmo@gmail.com>
|
||||||
|
|
@ -391,9 +432,12 @@ Google Inc.
|
||||||
Gordon Klaus <gordon.klaus@gmail.com>
|
Gordon Klaus <gordon.klaus@gmail.com>
|
||||||
Graham King <graham4king@gmail.com>
|
Graham King <graham4king@gmail.com>
|
||||||
Graham Miller <graham.miller@gmail.com>
|
Graham Miller <graham.miller@gmail.com>
|
||||||
|
Grant Griffiths <ggp493@gmail.com>
|
||||||
Greg Poirier <greg.istehbest@gmail.com>
|
Greg Poirier <greg.istehbest@gmail.com>
|
||||||
Greg Ward <greg@gerg.ca>
|
Greg Ward <greg@gerg.ca>
|
||||||
Gregory Man <man.gregory@gmail.com>
|
Gregory Man <man.gregory@gmail.com>
|
||||||
|
Guilherme Garnier <guilherme.garnier@gmail.com>
|
||||||
|
Guilherme Rezende <guilhermebr@gmail.com>
|
||||||
Guillaume J. Charmes <guillaume@charmes.net>
|
Guillaume J. Charmes <guillaume@charmes.net>
|
||||||
Guobiao Mei <meiguobiao@gmail.com>
|
Guobiao Mei <meiguobiao@gmail.com>
|
||||||
Gustav Paul <gustav.paul@gmail.com>
|
Gustav Paul <gustav.paul@gmail.com>
|
||||||
|
|
@ -404,6 +448,7 @@ Gyu-Ho Lee <gyuhox@gmail.com>
|
||||||
H. İbrahim Güngör <igungor@gmail.com>
|
H. İbrahim Güngör <igungor@gmail.com>
|
||||||
Hajime Hoshi <hajimehoshi@gmail.com>
|
Hajime Hoshi <hajimehoshi@gmail.com>
|
||||||
Hang Qian <hangqian90@gmail.com>
|
Hang Qian <hangqian90@gmail.com>
|
||||||
|
Hanjun Kim <hallazzang@gmail.com>
|
||||||
Hari haran <hariharan.uno@gmail.com>
|
Hari haran <hariharan.uno@gmail.com>
|
||||||
Hariharan Srinath <srinathh@gmail.com>
|
Hariharan Srinath <srinathh@gmail.com>
|
||||||
Harley Laue <losinggeneration@gmail.com>
|
Harley Laue <losinggeneration@gmail.com>
|
||||||
|
|
@ -416,8 +461,12 @@ Hector Martin Cantero <hector@marcansoft.com>
|
||||||
Henning Schmiedehausen <henning@schmiedehausen.org>
|
Henning Schmiedehausen <henning@schmiedehausen.org>
|
||||||
Henrik Edwards <henrik.edwards@gmail.com>
|
Henrik Edwards <henrik.edwards@gmail.com>
|
||||||
Henrik Hodne <henrik@hodne.io>
|
Henrik Hodne <henrik@hodne.io>
|
||||||
|
Henry Adi Sumarto <henry.adisumarto@gmail.com>
|
||||||
|
Henry Bubert <google@mindeco.de>
|
||||||
Henry Chang <mr.changyuheng@gmail.com>
|
Henry Chang <mr.changyuheng@gmail.com>
|
||||||
Herbert Georg Fischer <herbert.fischer@gmail.com>
|
Herbert Georg Fischer <herbert.fischer@gmail.com>
|
||||||
|
Hilko Bengen <bengen@hilluzination.de>
|
||||||
|
Hiroaki Nakamura <hnakamur@gmail.com>
|
||||||
Hironao OTSUBO <motemen@gmail.com>
|
Hironao OTSUBO <motemen@gmail.com>
|
||||||
Hiroshi Ioka <hirochachacha@gmail.com>
|
Hiroshi Ioka <hirochachacha@gmail.com>
|
||||||
Hitoshi Mitake <mitake.hitoshi@gmail.com>
|
Hitoshi Mitake <mitake.hitoshi@gmail.com>
|
||||||
|
|
@ -428,6 +477,7 @@ Hsin-Ho Yeh <yhh92u@gmail.com>
|
||||||
Hu Keping <hukeping@huawei.com>
|
Hu Keping <hukeping@huawei.com>
|
||||||
Hugues Bruant <hugues.bruant@gmail.com>
|
Hugues Bruant <hugues.bruant@gmail.com>
|
||||||
Ian Gudger <ian@loosescre.ws>
|
Ian Gudger <ian@loosescre.ws>
|
||||||
|
Ian Kent <iankent85@gmail.com>
|
||||||
IBM
|
IBM
|
||||||
Ibrahim AshShohail <ibra.sho@gmail.com>
|
Ibrahim AshShohail <ibra.sho@gmail.com>
|
||||||
Icarus Sparry <golang@icarus.freeuk.com>
|
Icarus Sparry <golang@icarus.freeuk.com>
|
||||||
|
|
@ -435,13 +485,16 @@ Iccha Sethi <icchasethi@gmail.com>
|
||||||
Idora Shinatose <idora.shinatose@gmail.com>
|
Idora Shinatose <idora.shinatose@gmail.com>
|
||||||
Igneous Systems, Inc.
|
Igneous Systems, Inc.
|
||||||
Igor Dolzhikov <bluesriverz@gmail.com>
|
Igor Dolzhikov <bluesriverz@gmail.com>
|
||||||
|
Igor Vashyst <ivashyst@gmail.com>
|
||||||
INADA Naoki <songofacandy@gmail.com>
|
INADA Naoki <songofacandy@gmail.com>
|
||||||
|
Inanc Gumus <m@inanc.io>
|
||||||
Ingo Krabbe <ikrabbe.ask@gmail.com>
|
Ingo Krabbe <ikrabbe.ask@gmail.com>
|
||||||
Ingo Oeser <nightlyone@googlemail.com>
|
Ingo Oeser <nightlyone@googlemail.com>
|
||||||
Intel Corporation
|
Intel Corporation
|
||||||
Irieda Noboru <irieda@gmail.com>
|
Irieda Noboru <irieda@gmail.com>
|
||||||
Isaac Wagner <ibw@isaacwagner.me>
|
Isaac Wagner <ibw@isaacwagner.me>
|
||||||
Ivan Babrou <ivan@cloudflare.com>
|
Ivan Babrou <ivan@cloudflare.com>
|
||||||
|
Ivan Bertona <ivan.bertona@gmail.com>
|
||||||
Ivan Moscoso <moscoso@gmail.com>
|
Ivan Moscoso <moscoso@gmail.com>
|
||||||
Ivan Ukhov <ivan.ukhov@gmail.com>
|
Ivan Ukhov <ivan.ukhov@gmail.com>
|
||||||
Jacob Hoffman-Andrews <github@hoffman-andrews.com>
|
Jacob Hoffman-Andrews <github@hoffman-andrews.com>
|
||||||
|
|
@ -455,6 +508,7 @@ James David Chalfant <james.chalfant@gmail.com>
|
||||||
James Fysh <james.fysh@gmail.com>
|
James Fysh <james.fysh@gmail.com>
|
||||||
James Gray <james@james4k.com>
|
James Gray <james@james4k.com>
|
||||||
James Hartig <fastest963@gmail.com>
|
James Hartig <fastest963@gmail.com>
|
||||||
|
James Lawrence <jljatone@gmail.com>
|
||||||
James Meneghello <rawrz0r@gmail.com>
|
James Meneghello <rawrz0r@gmail.com>
|
||||||
James Myers <jfmyers9@gmail.com>
|
James Myers <jfmyers9@gmail.com>
|
||||||
James Neve <jamesoneve@gmail.com>
|
James Neve <jamesoneve@gmail.com>
|
||||||
|
|
@ -463,6 +517,7 @@ James Schofield <james@shoeboxapp.com>
|
||||||
James Smith <jrs1995@icloud.com>
|
James Smith <jrs1995@icloud.com>
|
||||||
James Sweet <james.sweet88@googlemail.com>
|
James Sweet <james.sweet88@googlemail.com>
|
||||||
James Toy <nil@opensesame.st>
|
James Toy <nil@opensesame.st>
|
||||||
|
James Treanor <jtreanor3@gmail.com>
|
||||||
James Whitehead <jnwhiteh@gmail.com>
|
James Whitehead <jnwhiteh@gmail.com>
|
||||||
Jamie Beverly <jamie.r.beverly@gmail.com>
|
Jamie Beverly <jamie.r.beverly@gmail.com>
|
||||||
Jamie Kerr <jkerr113@googlemail.com>
|
Jamie Kerr <jkerr113@googlemail.com>
|
||||||
|
|
@ -474,19 +529,25 @@ Jan Mercl <0xjnml@gmail.com> <befelemepeseveze@gmail.com>
|
||||||
Jan Newmarch <jan.newmarch@gmail.com>
|
Jan Newmarch <jan.newmarch@gmail.com>
|
||||||
Jan Ziak <0xe2.0x9a.0x9b@gmail.com>
|
Jan Ziak <0xe2.0x9a.0x9b@gmail.com>
|
||||||
Jani Monoses <jani.monoses@ubuntu.com>
|
Jani Monoses <jani.monoses@ubuntu.com>
|
||||||
|
Jared Culp <jculp14@gmail.com>
|
||||||
Jaroslavas Počepko <jp@webmaster.ms>
|
Jaroslavas Počepko <jp@webmaster.ms>
|
||||||
Jason Barnett <jason.w.barnett@gmail.com>
|
Jason Barnett <jason.w.barnett@gmail.com>
|
||||||
Jason Chu <jasonchujc@gmail.com>
|
Jason Chu <jasonchujc@gmail.com>
|
||||||
Jason Del Ponte <delpontej@gmail.com>
|
Jason Del Ponte <delpontej@gmail.com>
|
||||||
Jason Smale <jsmale@zendesk.com>
|
Jason Smale <jsmale@zendesk.com>
|
||||||
Jason Travis <infomaniac7@gmail.com>
|
Jason Travis <infomaniac7@gmail.com>
|
||||||
|
Jason Wangsadinata <jwangsadinata@gmail.com>
|
||||||
|
Javier Segura <javism@gmail.com>
|
||||||
Jay Weisskopf <jay@jayschwa.net>
|
Jay Weisskopf <jay@jayschwa.net>
|
||||||
|
Jean-Francois Cantin <jfcantin@gmail.com>
|
||||||
Jean-Nicolas Moal <jn.moal@gmail.com>
|
Jean-Nicolas Moal <jn.moal@gmail.com>
|
||||||
|
Jeet Parekh <jeetparekh96@gmail.com>
|
||||||
Jeff Hodges <jeff@somethingsimilar.com>
|
Jeff Hodges <jeff@somethingsimilar.com>
|
||||||
Jeff R. Allen <jra@nella.org>
|
Jeff R. Allen <jra@nella.org>
|
||||||
Jeff Sickel <jas@corpus-callosum.com>
|
Jeff Sickel <jas@corpus-callosum.com>
|
||||||
Jeff Wendling <jeff@spacemonkey.com>
|
Jeff Wendling <jeff@spacemonkey.com>
|
||||||
Jeffrey H <jeffreyh192@gmail.com>
|
Jeffrey H <jeffreyh192@gmail.com>
|
||||||
|
Jelte Fennema <github-tech@jeltef.nl>
|
||||||
Jens Frederich <jfrederich@gmail.com>
|
Jens Frederich <jfrederich@gmail.com>
|
||||||
Jeremy Jackins <jeremyjackins@gmail.com>
|
Jeremy Jackins <jeremyjackins@gmail.com>
|
||||||
Jeroen Bobbeldijk <jerbob92@gmail.com>
|
Jeroen Bobbeldijk <jerbob92@gmail.com>
|
||||||
|
|
@ -494,12 +555,14 @@ Jess Frazelle <me@jessfraz.com>
|
||||||
Jesse Szwedko <jesse.szwedko@gmail.com>
|
Jesse Szwedko <jesse.szwedko@gmail.com>
|
||||||
Jihyun Yu <yjh0502@gmail.com>
|
Jihyun Yu <yjh0502@gmail.com>
|
||||||
Jim McGrath <jimmc2@gmail.com>
|
Jim McGrath <jimmc2@gmail.com>
|
||||||
|
Jimmy Frasche <soapboxcicero@gmail.com>
|
||||||
Jimmy Zelinskie <jimmyzelinskie@gmail.com>
|
Jimmy Zelinskie <jimmyzelinskie@gmail.com>
|
||||||
Jin-wook Jeong <jeweljar@hanmail.net>
|
Jin-wook Jeong <jeweljar@hanmail.net>
|
||||||
Jingcheng Zhang <diogin@gmail.com>
|
Jingcheng Zhang <diogin@gmail.com>
|
||||||
Jingguo Yao <yaojingguo@gmail.com>
|
Jingguo Yao <yaojingguo@gmail.com>
|
||||||
Jiong Du <londevil@gmail.com>
|
Jiong Du <londevil@gmail.com>
|
||||||
Jirka Daněk <dnk@mail.muni.cz>
|
Jirka Daněk <dnk@mail.muni.cz>
|
||||||
|
Jiulong Wang <jiulongw@gmail.com>
|
||||||
Joakim Sernbrant <serbaut@gmail.com>
|
Joakim Sernbrant <serbaut@gmail.com>
|
||||||
Joe Farrell <joe2farrell@gmail.com>
|
Joe Farrell <joe2farrell@gmail.com>
|
||||||
Joe Harrison <joehazzers@gmail.com>
|
Joe Harrison <joehazzers@gmail.com>
|
||||||
|
|
@ -545,14 +608,18 @@ Josh Goebel <dreamer3@gmail.com>
|
||||||
Josh Holland <jrh@joshh.co.uk>
|
Josh Holland <jrh@joshh.co.uk>
|
||||||
Josh Roppo <joshroppo@gmail.com>
|
Josh Roppo <joshroppo@gmail.com>
|
||||||
Joshua Chase <jcjoshuachase@gmail.com>
|
Joshua Chase <jcjoshuachase@gmail.com>
|
||||||
|
Joshua Rubin <joshua@rubixconsulting.com>
|
||||||
Josselin Costanzi <josselin@costanzi.fr>
|
Josselin Costanzi <josselin@costanzi.fr>
|
||||||
Jostein Stuhaug <js@solidsystem.no>
|
Jostein Stuhaug <js@solidsystem.no>
|
||||||
Joyent, Inc.
|
Joyent, Inc.
|
||||||
JT Olds <jtolds@xnet5.com>
|
JT Olds <jtolds@xnet5.com>
|
||||||
|
Juan Carlos <juanjcsr@gmail.com>
|
||||||
|
Jude Pereira <judebpereira@gmail.com>
|
||||||
Jukka-Pekka Kekkonen <karatepekka@gmail.com>
|
Jukka-Pekka Kekkonen <karatepekka@gmail.com>
|
||||||
Julian Kornberger <jk+github@digineo.de>
|
Julian Kornberger <jk+github@digineo.de>
|
||||||
Julian Phillips <julian@quantumfyre.co.uk>
|
Julian Phillips <julian@quantumfyre.co.uk>
|
||||||
Julien Schmidt <google@julienschmidt.com>
|
Julien Schmidt <google@julienschmidt.com>
|
||||||
|
Junya Hayashi <ledmonster@gmail.com>
|
||||||
Justin Nuß <nuss.justin@gmail.com>
|
Justin Nuß <nuss.justin@gmail.com>
|
||||||
Justyn Temme <justyntemme@gmail.com>
|
Justyn Temme <justyntemme@gmail.com>
|
||||||
Kai Backman <kaib@golang.org>
|
Kai Backman <kaib@golang.org>
|
||||||
|
|
@ -562,7 +629,9 @@ Kaleb Elwert <kelwert@atlassian.com>
|
||||||
Kamil Chmielewski <kamil.chm@gmail.com>
|
Kamil Chmielewski <kamil.chm@gmail.com>
|
||||||
Kamil Kisiel <kamil@kamilkisiel.net> <kamil.kisiel@gmail.com>
|
Kamil Kisiel <kamil@kamilkisiel.net> <kamil.kisiel@gmail.com>
|
||||||
Kang Hu <hukangustc@gmail.com>
|
Kang Hu <hukangustc@gmail.com>
|
||||||
|
Karel Pazdera <pazderak@gmail.com>
|
||||||
Karoly Negyesi <chx1975@gmail.com>
|
Karoly Negyesi <chx1975@gmail.com>
|
||||||
|
Karsten Köhler <karsten.koehler95@gmail.com>
|
||||||
Kashav Madan <kshvmdn@gmail.com>
|
Kashav Madan <kshvmdn@gmail.com>
|
||||||
Kate Manson <kate.manson@izettle.com>
|
Kate Manson <kate.manson@izettle.com>
|
||||||
Kato Kazuyoshi <kato.kazuyoshi@gmail.com>
|
Kato Kazuyoshi <kato.kazuyoshi@gmail.com>
|
||||||
|
|
@ -579,13 +648,17 @@ Ken Friedenbach <kenliz@cruzio.com>
|
||||||
Ken Rockot <ken@oz.gs>
|
Ken Rockot <ken@oz.gs>
|
||||||
Ken Sedgwick <ken@bonsai.com>
|
Ken Sedgwick <ken@bonsai.com>
|
||||||
Kenji Kaneda <kenji.kaneda@gmail.com>
|
Kenji Kaneda <kenji.kaneda@gmail.com>
|
||||||
|
Kenji Yano <kenji.yano@gmail.com>
|
||||||
Kenneth Shaw <kenshaw@gmail.com>
|
Kenneth Shaw <kenshaw@gmail.com>
|
||||||
Kenny Grant <kennygrant@gmail.com>
|
Kenny Grant <kennygrant@gmail.com>
|
||||||
Kevin Ballard <kevin@sb.org>
|
Kevin Ballard <kevin@sb.org>
|
||||||
Kevin Burke <kev@inburke.com>
|
Kevin Burke <kev@inburke.com>
|
||||||
Kevin Kirsche <kev.kirsche@gmail.com>
|
Kevin Kirsche <kev.kirsche@gmail.com>
|
||||||
|
Kevin Ruffin <kruffin@gmail.com>
|
||||||
Kevin Vu <kevin.m.vu@gmail.com>
|
Kevin Vu <kevin.m.vu@gmail.com>
|
||||||
|
Kieran Colford <kieran@kcolford.com>
|
||||||
Kim Yongbin <kybinz@gmail.com>
|
Kim Yongbin <kybinz@gmail.com>
|
||||||
|
Kirk Han <kirk91.han@gmail.com>
|
||||||
Klaus Post <klauspost@gmail.com>
|
Klaus Post <klauspost@gmail.com>
|
||||||
Kodie Goodwin <kodiegoodwin@gmail.com>
|
Kodie Goodwin <kodiegoodwin@gmail.com>
|
||||||
Koichi Shiraishi <zchee.io@gmail.com>
|
Koichi Shiraishi <zchee.io@gmail.com>
|
||||||
|
|
@ -596,20 +669,26 @@ KPCompass, Inc.
|
||||||
Kris Nova <kris@nivenly.com>
|
Kris Nova <kris@nivenly.com>
|
||||||
Kristopher Watts <traetox@gmail.com>
|
Kristopher Watts <traetox@gmail.com>
|
||||||
Kun Li <likunarmstrong@gmail.com>
|
Kun Li <likunarmstrong@gmail.com>
|
||||||
|
Kunpei Sakai <namusyaka@gmail.com>
|
||||||
Kyle Consalus <consalus@gmail.com>
|
Kyle Consalus <consalus@gmail.com>
|
||||||
Kyle Isom <kyle@gokyle.net>
|
Kyle Isom <kyle@gokyle.net>
|
||||||
Kyle Jones <kyle@kyledj.com>
|
Kyle Jones <kyle@kyledj.com>
|
||||||
Kyle Lemons <kyle@kylelemons.net>
|
Kyle Lemons <kyle@kylelemons.net>
|
||||||
|
Kyle Shannon <kyle@pobox.com>
|
||||||
|
Kyohei Kadota <lufia@lufia.org>
|
||||||
Kyrylo Silin <silin@kyrylo.org>
|
Kyrylo Silin <silin@kyrylo.org>
|
||||||
L Campbell <unpantsu@gmail.com>
|
L Campbell <unpantsu@gmail.com>
|
||||||
Lai Jiangshan <eag0628@gmail.com>
|
Lai Jiangshan <eag0628@gmail.com>
|
||||||
|
Lakshay Garg <lakshay.garg.1996@gmail.com>
|
||||||
Lars Jeppesen <jeppesen.lars@gmail.com>
|
Lars Jeppesen <jeppesen.lars@gmail.com>
|
||||||
Lars Wiegman <lars@namsral.com>
|
Lars Wiegman <lars@namsral.com>
|
||||||
Larz Conwell <larzconwell@gmail.com>
|
Larz Conwell <larzconwell@gmail.com>
|
||||||
|
Laurent Voisin <lpvoisin@gmail.com>
|
||||||
Laurie Clark-Michalek <laurie@qubit.com>
|
Laurie Clark-Michalek <laurie@qubit.com>
|
||||||
LE Manh Cuong <cuong.manhle.vn@gmail.com>
|
LE Manh Cuong <cuong.manhle.vn@gmail.com>
|
||||||
Lee Hinman <hinman@gmail.com>
|
Lee Hinman <hinman@gmail.com>
|
||||||
Lee Packham <lpackham@gmail.com>
|
Lee Packham <lpackham@gmail.com>
|
||||||
|
Leigh McCulloch <leighmcc@gmail.com>
|
||||||
Leon Klingele <git@leonklingele.de>
|
Leon Klingele <git@leonklingele.de>
|
||||||
Lev Shamardin <shamardin@gmail.com>
|
Lev Shamardin <shamardin@gmail.com>
|
||||||
Lewin Bormann <lewin.bormann@gmail.com>
|
Lewin Bormann <lewin.bormann@gmail.com>
|
||||||
|
|
@ -629,10 +708,15 @@ Luigi Riefolo <luigi.riefolo@gmail.com>
|
||||||
Luit van Drongelen <luitvd@gmail.com>
|
Luit van Drongelen <luitvd@gmail.com>
|
||||||
Luka Zakrajšek <tr00.g33k@gmail.com>
|
Luka Zakrajšek <tr00.g33k@gmail.com>
|
||||||
Luke Curley <qpingu@gmail.com>
|
Luke Curley <qpingu@gmail.com>
|
||||||
|
Luke Granger-Brown <git@lukegb.com>
|
||||||
|
Lyle Franklin <lylejfranklin@gmail.com>
|
||||||
Ma Peiqi <mapeiqi2017@gmail.com>
|
Ma Peiqi <mapeiqi2017@gmail.com>
|
||||||
|
Maicon Costa <maiconscosta@gmail.com>
|
||||||
Maksym Trykur <maksym.trykur@gmail.com>
|
Maksym Trykur <maksym.trykur@gmail.com>
|
||||||
Mal Curtis <mal@mal.co.nz>
|
Mal Curtis <mal@mal.co.nz>
|
||||||
Manfred Touron <m@42.am>
|
Manfred Touron <m@42.am>
|
||||||
|
Manish Goregaokar <manishsmail@gmail.com>
|
||||||
|
Mansour Rahimi <rahimi.mnr@gmail.com>
|
||||||
Manu S Ajith <neo@codingarena.in>
|
Manu S Ajith <neo@codingarena.in>
|
||||||
Manuel Mendez <mmendez534@gmail.com>
|
Manuel Mendez <mmendez534@gmail.com>
|
||||||
Marc Weistroff <marc@weistroff.net>
|
Marc Weistroff <marc@weistroff.net>
|
||||||
|
|
@ -642,8 +726,11 @@ Marco Hennings <marco.hennings@freiheit.com>
|
||||||
Marin Bašić <marin.basic02@gmail.com>
|
Marin Bašić <marin.basic02@gmail.com>
|
||||||
Mark Adams <mark@markadams.me>
|
Mark Adams <mark@markadams.me>
|
||||||
Mark Bucciarelli <mkbucc@gmail.com>
|
Mark Bucciarelli <mkbucc@gmail.com>
|
||||||
|
Mark Percival <m@mdp.im>
|
||||||
|
Mark Pulford <mark@kyne.com.au>
|
||||||
Mark Severson <miquella@gmail.com>
|
Mark Severson <miquella@gmail.com>
|
||||||
Mark Theunissen <mark.theunissen@gmail.com>
|
Mark Theunissen <mark.theunissen@gmail.com>
|
||||||
|
Mark Wolfe <mark@wolfe.id.au>
|
||||||
Marko Juhani Silokunnas <marko.silokunnas@gmail.com>
|
Marko Juhani Silokunnas <marko.silokunnas@gmail.com>
|
||||||
Marko Mudrinic <mudrinic.mare@gmail.com>
|
Marko Mudrinic <mudrinic.mare@gmail.com>
|
||||||
Marko Tiikkaja <marko@joh.to>
|
Marko Tiikkaja <marko@joh.to>
|
||||||
|
|
@ -661,13 +748,17 @@ Martin Neubauer <m.ne@gmx.net>
|
||||||
Martin Olsen <github.com@martinolsen.net>
|
Martin Olsen <github.com@martinolsen.net>
|
||||||
Martin Olsson <martin@minimum.se>
|
Martin Olsson <martin@minimum.se>
|
||||||
Martin Probst <martin@probst.io>
|
Martin Probst <martin@probst.io>
|
||||||
|
Martins Sipenko <martins.sipenko@gmail.com>
|
||||||
Marvin Stenger <marvin.stenger94@gmail.com>
|
Marvin Stenger <marvin.stenger94@gmail.com>
|
||||||
Marwan Sulaiman <marwan.sulaiman@work.co>
|
Marwan Sulaiman <marwan.sulaiman@work.co>
|
||||||
Maryan Hratson <gmarik@gmail.com>
|
Maryan Hratson <gmarik@gmail.com>
|
||||||
Masahiro Furudate <masahiro.furudate@gmail.com>
|
Masahiro Furudate <masahiro.furudate@gmail.com>
|
||||||
Masahiro Wakame <vvakame@gmail.com>
|
Masahiro Wakame <vvakame@gmail.com>
|
||||||
Masaki Yoshida <yoshida.masaki@gmail.com>
|
Masaki Yoshida <yoshida.masaki@gmail.com>
|
||||||
|
Mat Byczkowski <mbyczkowski@gmail.com>
|
||||||
Máté Gulyás <mgulyas86@gmail.com>
|
Máté Gulyás <mgulyas86@gmail.com>
|
||||||
|
Matej Baćo <matejbaco@gmail.com>
|
||||||
|
Mateus Amin <mateus.amin@gmail.com>
|
||||||
Mateusz Czapliński <czapkofan@gmail.com>
|
Mateusz Czapliński <czapkofan@gmail.com>
|
||||||
Mathias Beke <git@denbeke.be>
|
Mathias Beke <git@denbeke.be>
|
||||||
Mathias Hall-Andersen <mathias@hall-andersen.dk>
|
Mathias Hall-Andersen <mathias@hall-andersen.dk>
|
||||||
|
|
@ -677,6 +768,7 @@ Mats Lidell <mats.lidell@cag.se>
|
||||||
Matt Aimonetti <mattaimonetti@gmail.com>
|
Matt Aimonetti <mattaimonetti@gmail.com>
|
||||||
Matt Blair <me@matthewblair.net>
|
Matt Blair <me@matthewblair.net>
|
||||||
Matt Bostock <matt@mattbostock.com>
|
Matt Bostock <matt@mattbostock.com>
|
||||||
|
Matt Dee <mdee@hioscar.com>
|
||||||
Matt Drollette <matt@drollette.com>
|
Matt Drollette <matt@drollette.com>
|
||||||
Matt Harden <matt.harden@gmail.com>
|
Matt Harden <matt.harden@gmail.com>
|
||||||
Matt Jibson <matt.jibson@gmail.com>
|
Matt Jibson <matt.jibson@gmail.com>
|
||||||
|
|
@ -688,23 +780,28 @@ Matt Strong <mstrong1341@gmail.com>
|
||||||
Matt T. Proud <matt.proud@gmail.com>
|
Matt T. Proud <matt.proud@gmail.com>
|
||||||
Matt Williams <gh@mattyw.net>
|
Matt Williams <gh@mattyw.net>
|
||||||
Matthew Brennan <matty.brennan@gmail.com>
|
Matthew Brennan <matty.brennan@gmail.com>
|
||||||
|
Matthew Broberg <matthewbbroberg@gmail.com>
|
||||||
Matthew Cottingham <mattcottingham@gmail.com>
|
Matthew Cottingham <mattcottingham@gmail.com>
|
||||||
Matthew Denton <mdenton@skyportsystems.com>
|
Matthew Denton <mdenton@skyportsystems.com>
|
||||||
Matthew Holt <Matthew.Holt+git@gmail.com>
|
Matthew Holt <Matthew.Holt+git@gmail.com>
|
||||||
Matthew Horsnell <matthew.horsnell@gmail.com>
|
Matthew Horsnell <matthew.horsnell@gmail.com>
|
||||||
Matthieu Hauglustaine <matt.hauglustaine@gmail.com>
|
Matthieu Hauglustaine <matt.hauglustaine@gmail.com>
|
||||||
Matthieu Olivier <olivier.matthieu@gmail.com>
|
Matthieu Olivier <olivier.matthieu@gmail.com>
|
||||||
|
Matthijs Kooijman <matthijs@stdin.nl>
|
||||||
Max Riveiro <kavu13@gmail.com>
|
Max Riveiro <kavu13@gmail.com>
|
||||||
|
Max Schmitt <max@schmitt.mx>
|
||||||
Maxim Khitrov <max@mxcrypt.com>
|
Maxim Khitrov <max@mxcrypt.com>
|
||||||
Maxime de Roucy <maxime.deroucy@gmail.com>
|
Maxime de Roucy <maxime.deroucy@gmail.com>
|
||||||
Máximo Cuadros Ortiz <mcuadros@gmail.com>
|
Máximo Cuadros Ortiz <mcuadros@gmail.com>
|
||||||
Maxwell Krohn <themax@gmail.com>
|
Maxwell Krohn <themax@gmail.com>
|
||||||
|
Mayank Kumar <krmayankk@gmail.com>
|
||||||
MediaMath, Inc
|
MediaMath, Inc
|
||||||
Meir Fischer <meirfischer@gmail.com>
|
Meir Fischer <meirfischer@gmail.com>
|
||||||
Meng Zhuo <mengzhuo1203@gmail.com>
|
Meng Zhuo <mengzhuo1203@gmail.com>
|
||||||
Meteor Development Group
|
Meteor Development Group
|
||||||
Mhd Sulhan <m.shulhan@gmail.com>
|
Mhd Sulhan <m.shulhan@gmail.com>
|
||||||
Micah Stetson <micah.stetson@gmail.com>
|
Micah Stetson <micah.stetson@gmail.com>
|
||||||
|
Michael Brandenburg <mbrandenburg@bolste.com>
|
||||||
Michael Chaten <mchaten@gmail.com>
|
Michael Chaten <mchaten@gmail.com>
|
||||||
Michael Edwards <medwards@walledcity.ca>
|
Michael Edwards <medwards@walledcity.ca>
|
||||||
Michael Elkins <michael.elkins@gmail.com>
|
Michael Elkins <michael.elkins@gmail.com>
|
||||||
|
|
@ -716,17 +813,22 @@ Michael Käufl <golang@c.michael-kaeufl.de>
|
||||||
Michael Lewis <mikelikespie@gmail.com>
|
Michael Lewis <mikelikespie@gmail.com>
|
||||||
Michael MacInnis <Michael.P.MacInnis@gmail.com>
|
Michael MacInnis <Michael.P.MacInnis@gmail.com>
|
||||||
Michael McConville <momcconville@gmail.com>
|
Michael McConville <momcconville@gmail.com>
|
||||||
|
Michael McLoughlin <mmcloughlin@gmail.com>
|
||||||
Michael Pearson <mipearson@gmail.com>
|
Michael Pearson <mipearson@gmail.com>
|
||||||
Michael Schaller <michael@5challer.de>
|
Michael Schaller <michael@5challer.de>
|
||||||
|
Michael Schurter <michael.schurter@gmail.com>
|
||||||
Michael Stapelberg <michael@stapelberg.de>
|
Michael Stapelberg <michael@stapelberg.de>
|
||||||
|
Michael Steinert <mike.steinert@gmail.com>
|
||||||
Michael Teichgräber <mteichgraeber@gmx.de>
|
Michael Teichgräber <mteichgraeber@gmx.de>
|
||||||
Michael Vetter <g.bluehut@gmail.com>
|
Michael Vetter <g.bluehut@gmail.com>
|
||||||
Michal Bohuslávek <mbohuslavek@gmail.com>
|
Michal Bohuslávek <mbohuslavek@gmail.com>
|
||||||
Michał Derkacz <ziutek@lnet.pl>
|
Michał Derkacz <ziutek@lnet.pl>
|
||||||
|
Michal Pristas <michal.pristas@gmail.com>
|
||||||
Miek Gieben <miek@miek.nl>
|
Miek Gieben <miek@miek.nl>
|
||||||
Miguel Mendez <stxmendez@gmail.com>
|
Miguel Mendez <stxmendez@gmail.com>
|
||||||
Miguel Molina <hi@mvader.me>
|
Miguel Molina <hi@mvader.me>
|
||||||
Mihai Borobocea <MihaiBorobocea@gmail.com>
|
Mihai Borobocea <MihaiBorobocea@gmail.com>
|
||||||
|
Mihail Minaev <minaev.mike@gmail.com>
|
||||||
Mikael Tillenius <mikti42@gmail.com>
|
Mikael Tillenius <mikti42@gmail.com>
|
||||||
Mike Andrews <mra@xoba.com>
|
Mike Andrews <mra@xoba.com>
|
||||||
Mike Appleby <mike@app.leby.org>
|
Mike Appleby <mike@app.leby.org>
|
||||||
|
|
@ -748,9 +850,11 @@ Moriyoshi Koizumi <mozo@mozo.jp>
|
||||||
Morten Siebuhr <sbhr@sbhr.dk>
|
Morten Siebuhr <sbhr@sbhr.dk>
|
||||||
Môshe van der Sterre <moshevds@gmail.com>
|
Môshe van der Sterre <moshevds@gmail.com>
|
||||||
Mostyn Bramley-Moore <mostyn@antipode.se>
|
Mostyn Bramley-Moore <mostyn@antipode.se>
|
||||||
|
Muhammad Falak R Wani <falakreyaz@gmail.com>
|
||||||
Muhammed Uluyol <uluyol0@gmail.com>
|
Muhammed Uluyol <uluyol0@gmail.com>
|
||||||
Mura Li <mura_li@castech.com.tw>
|
Mura Li <mura_li@castech.com.tw>
|
||||||
Nan Deng <monnand@gmail.com>
|
Nan Deng <monnand@gmail.com>
|
||||||
|
Naoki Kanatani <k12naoki@gmail.com>
|
||||||
Nathan Caza <mastercactapus@gmail.com>
|
Nathan Caza <mastercactapus@gmail.com>
|
||||||
Nathan Humphreys <nkhumphreys@gmail.com>
|
Nathan Humphreys <nkhumphreys@gmail.com>
|
||||||
Nathan John Youngman <nj@nathany.com>
|
Nathan John Youngman <nj@nathany.com>
|
||||||
|
|
@ -779,6 +883,7 @@ Nick Miyake <nmiyake@users.noreply.github.com>
|
||||||
Nick Patavalis <nick.patavalis@gmail.com>
|
Nick Patavalis <nick.patavalis@gmail.com>
|
||||||
Nick Petroni <npetroni@cs.umd.edu>
|
Nick Petroni <npetroni@cs.umd.edu>
|
||||||
Nick Robinson <nrobinson13@gmail.com>
|
Nick Robinson <nrobinson13@gmail.com>
|
||||||
|
Nicolas BRULEZ <n.brulez@gmail.com>
|
||||||
Nicolas Kaiser <nikai@nikai.net>
|
Nicolas Kaiser <nikai@nikai.net>
|
||||||
Nicolas Owens <mischief@offblast.org>
|
Nicolas Owens <mischief@offblast.org>
|
||||||
Nicolas S. Dade <nic.dade@gmail.com>
|
Nicolas S. Dade <nic.dade@gmail.com>
|
||||||
|
|
@ -788,8 +893,10 @@ Nik Nyby <nnyby@columbia.edu>
|
||||||
Niklas Schnelle <niklas.schnelle@gmail.com>
|
Niklas Schnelle <niklas.schnelle@gmail.com>
|
||||||
Niko Dziemba <niko@dziemba.com>
|
Niko Dziemba <niko@dziemba.com>
|
||||||
Nikolay Turpitko <nikolay@turpitko.com>
|
Nikolay Turpitko <nikolay@turpitko.com>
|
||||||
|
Nils Larsgård <nilsmagnus@gmail.com>
|
||||||
Niranjan Godbole <niranjan8192@gmail.com>
|
Niranjan Godbole <niranjan8192@gmail.com>
|
||||||
Noah Campbell <noahcampbell@gmail.com>
|
Noah Campbell <noahcampbell@gmail.com>
|
||||||
|
Noble Johnson <noblepoly@gmail.com>
|
||||||
Norberto Lopes <nlopes.ml@gmail.com>
|
Norberto Lopes <nlopes.ml@gmail.com>
|
||||||
Odin Ugedal <odin@ugedal.com>
|
Odin Ugedal <odin@ugedal.com>
|
||||||
Oleg Bulatov <dmage@yandex-team.ru>
|
Oleg Bulatov <dmage@yandex-team.ru>
|
||||||
|
|
@ -823,12 +930,15 @@ Patrick Mylund Nielsen <patrick@patrickmn.com>
|
||||||
Patrick Pelletier <pp.pelletier@gmail.com>
|
Patrick Pelletier <pp.pelletier@gmail.com>
|
||||||
Patrick Smith <pat42smith@gmail.com>
|
Patrick Smith <pat42smith@gmail.com>
|
||||||
Paul A Querna <paul.querna@gmail.com>
|
Paul A Querna <paul.querna@gmail.com>
|
||||||
|
Paul Boyd <boyd.paul2@gmail.com>
|
||||||
Paul Hammond <paul@paulhammond.org>
|
Paul Hammond <paul@paulhammond.org>
|
||||||
Paul Jolly <paul@myitcv.org.uk>
|
Paul Jolly <paul@myitcv.org.uk>
|
||||||
Paul Lalonde <paul.a.lalonde@gmail.com>
|
Paul Lalonde <paul.a.lalonde@gmail.com>
|
||||||
Paul Meyer <paul.meyer@microsoft.com>
|
Paul Meyer <paul.meyer@microsoft.com>
|
||||||
|
Paul PISCUC <paul.piscuc@gmail.com>
|
||||||
Paul Querna <pquerna@apache.org>
|
Paul Querna <pquerna@apache.org>
|
||||||
Paul Rosania <paul.rosania@gmail.com>
|
Paul Rosania <paul.rosania@gmail.com>
|
||||||
|
Paul Ruest <pruest@gmail.com>
|
||||||
Paul Sbarra <Sbarra.Paul@gmail.com>
|
Paul Sbarra <Sbarra.Paul@gmail.com>
|
||||||
Paul Smith <paulsmith@pobox.com> <paulsmith@gmail.com>
|
Paul Smith <paulsmith@pobox.com> <paulsmith@gmail.com>
|
||||||
Paul van Brouwershaven <paul@vanbrouwershaven.com>
|
Paul van Brouwershaven <paul@vanbrouwershaven.com>
|
||||||
|
|
@ -853,6 +963,7 @@ Péter Szilágyi <peterke@gmail.com>
|
||||||
Peter Waldschmidt <peter@waldschmidt.com>
|
Peter Waldschmidt <peter@waldschmidt.com>
|
||||||
Peter Waller <peter.waller@gmail.com>
|
Peter Waller <peter.waller@gmail.com>
|
||||||
Peter Williams <pwil3058@gmail.com>
|
Peter Williams <pwil3058@gmail.com>
|
||||||
|
Petrica Voicu <pvoicu@paypal.com>
|
||||||
Philip Børgesen <philip.borgesen@gmail.com>
|
Philip Børgesen <philip.borgesen@gmail.com>
|
||||||
Philip Hofer <phofer@umich.edu>
|
Philip Hofer <phofer@umich.edu>
|
||||||
Philip K. Warren <pkwarren@gmail.com>
|
Philip K. Warren <pkwarren@gmail.com>
|
||||||
|
|
@ -861,26 +972,34 @@ Pierre Roullon <pierre.roullon@gmail.com>
|
||||||
Piers <google@hellopiers.pro>
|
Piers <google@hellopiers.pro>
|
||||||
Pieter Droogendijk <pieter@binky.org.uk>
|
Pieter Droogendijk <pieter@binky.org.uk>
|
||||||
Pietro Gagliardi <pietro10@mac.com>
|
Pietro Gagliardi <pietro10@mac.com>
|
||||||
|
Pontus Leitzler <leitzler@gmail.com>
|
||||||
Prashant Varanasi <prashant@prashantv.com>
|
Prashant Varanasi <prashant@prashantv.com>
|
||||||
Pravendra Singh <hackpravj@gmail.com>
|
Pravendra Singh <hackpravj@gmail.com>
|
||||||
Preetam Jinka <pj@preet.am>
|
Preetam Jinka <pj@preet.am>
|
||||||
Qiuxuan Zhu <ilsh1022@gmail.com>
|
Qiuxuan Zhu <ilsh1022@gmail.com>
|
||||||
|
Qualcomm Data Center, Inc.
|
||||||
Quan Tran <qeed.quan@gmail.com>
|
Quan Tran <qeed.quan@gmail.com>
|
||||||
Quan Yong Zhai <qyzhai@gmail.com>
|
Quan Yong Zhai <qyzhai@gmail.com>
|
||||||
Quentin Perez <qperez@ocs.online.net>
|
Quentin Perez <qperez@ocs.online.net>
|
||||||
Quentin Renard <contact@asticode.com>
|
Quentin Renard <contact@asticode.com>
|
||||||
Quoc-Viet Nguyen <afelion@gmail.com>
|
Quoc-Viet Nguyen <afelion@gmail.com>
|
||||||
RackTop Systems Inc.
|
RackTop Systems Inc.
|
||||||
|
Radek Sohlich <sohlich@gmail.com>
|
||||||
Radu Berinde <radu@cockroachlabs.com>
|
Radu Berinde <radu@cockroachlabs.com>
|
||||||
Rafal Jeczalik <rjeczalik@gmail.com>
|
Rafal Jeczalik <rjeczalik@gmail.com>
|
||||||
Raif S. Naffah <go@naffah-raif.name>
|
Raif S. Naffah <go@naffah-raif.name>
|
||||||
RainTank
|
RainTank
|
||||||
Rajat Goel <rajat.goel2010@gmail.com>
|
Rajat Goel <rajat.goel2010@gmail.com>
|
||||||
|
Rajath Agasthya <rajathagasthya@gmail.com>
|
||||||
|
Rajender Reddy Kompally <rajenderreddykompally@gmail.com>
|
||||||
Ralph Corderoy <ralph@inputplus.co.uk>
|
Ralph Corderoy <ralph@inputplus.co.uk>
|
||||||
|
Ramazan AYYILDIZ <rayyildiz@gmail.com>
|
||||||
Raphael Geronimi <raphael.geronimi@gmail.com>
|
Raphael Geronimi <raphael.geronimi@gmail.com>
|
||||||
|
RaviTeja Pothana <ravi.tezu@gmail.com>
|
||||||
Ray Tung <rtung@thoughtworks.com>
|
Ray Tung <rtung@thoughtworks.com>
|
||||||
Raymond Kazlauskas <raima220@gmail.com>
|
Raymond Kazlauskas <raima220@gmail.com>
|
||||||
Red Hat, Inc.
|
Red Hat, Inc.
|
||||||
|
Reilly Watson <reillywatson@gmail.com>
|
||||||
Reinaldo de Souza Jr <juniorz@gmail.com>
|
Reinaldo de Souza Jr <juniorz@gmail.com>
|
||||||
Remi Gillig <remigillig@gmail.com>
|
Remi Gillig <remigillig@gmail.com>
|
||||||
Rémy Oudompheng <oudomphe@phare.normalesup.org>
|
Rémy Oudompheng <oudomphe@phare.normalesup.org>
|
||||||
|
|
@ -909,10 +1028,13 @@ Rodrigo Rafael Monti Kochenburger <divoxx@gmail.com>
|
||||||
Roger Pau Monné <royger@gmail.com>
|
Roger Pau Monné <royger@gmail.com>
|
||||||
Roger Peppe <rogpeppe@gmail.com>
|
Roger Peppe <rogpeppe@gmail.com>
|
||||||
Roland Shoemaker <rolandshoemaker@gmail.com>
|
Roland Shoemaker <rolandshoemaker@gmail.com>
|
||||||
|
Roman Budnikov <romanyx90@yandex.ru>
|
||||||
Ron Hashimoto <mail@h2so5.net>
|
Ron Hashimoto <mail@h2so5.net>
|
||||||
Ron Minnich <rminnich@gmail.com>
|
Ron Minnich <rminnich@gmail.com>
|
||||||
|
Ross Chater <rdchater@gmail.com>
|
||||||
Ross Light <rlight2@gmail.com>
|
Ross Light <rlight2@gmail.com>
|
||||||
Rowan Worth <sqweek@gmail.com>
|
Rowan Worth <sqweek@gmail.com>
|
||||||
|
Rudi Kramer <rudi.kramer@gmail.com>
|
||||||
Russell Haering <russellhaering@gmail.com>
|
Russell Haering <russellhaering@gmail.com>
|
||||||
Ryan Bagwell <ryanbagwell@outlook.com>
|
Ryan Bagwell <ryanbagwell@outlook.com>
|
||||||
Ryan Boehning <ryan.boehning@apcera.com>
|
Ryan Boehning <ryan.boehning@apcera.com>
|
||||||
|
|
@ -920,6 +1042,8 @@ Ryan Hitchman <hitchmanr@gmail.com>
|
||||||
Ryan Lower <rpjlower@gmail.com>
|
Ryan Lower <rpjlower@gmail.com>
|
||||||
Ryan Seys <ryan@ryanseys.com>
|
Ryan Seys <ryan@ryanseys.com>
|
||||||
Ryan Slade <ryanslade@gmail.com>
|
Ryan Slade <ryanslade@gmail.com>
|
||||||
|
Ryoichi KATO <ryo1kato@gmail.com>
|
||||||
|
Ryuji Iwata <qt.luigi@gmail.com>
|
||||||
Ryuzo Yamamoto <ryuzo.yamamoto@gmail.com>
|
Ryuzo Yamamoto <ryuzo.yamamoto@gmail.com>
|
||||||
S.Çağlar Onur <caglar@10ur.org>
|
S.Çağlar Onur <caglar@10ur.org>
|
||||||
Sakeven Jiang <jc5930@sina.cn>
|
Sakeven Jiang <jc5930@sina.cn>
|
||||||
|
|
@ -933,15 +1057,19 @@ Sascha Brawer <sascha@brawer.ch>
|
||||||
Sasha Sobol <sasha@scaledinference.com>
|
Sasha Sobol <sasha@scaledinference.com>
|
||||||
Scott Barron <scott.barron@github.com>
|
Scott Barron <scott.barron@github.com>
|
||||||
Scott Bell <scott@sctsm.com>
|
Scott Bell <scott@sctsm.com>
|
||||||
|
Scott Crunkleton <crunk1@gmail.com>
|
||||||
Scott Ferguson <scottwferg@gmail.com>
|
Scott Ferguson <scottwferg@gmail.com>
|
||||||
Scott Lawrence <bytbox@gmail.com>
|
Scott Lawrence <bytbox@gmail.com>
|
||||||
Sean Rees <sean@erifax.org>
|
Sean Rees <sean@erifax.org>
|
||||||
Sebastien Binet <seb.binet@gmail.com>
|
Sebastien Binet <seb.binet@gmail.com>
|
||||||
Sébastien Paolacci <sebastien.paolacci@gmail.com>
|
Sébastien Paolacci <sebastien.paolacci@gmail.com>
|
||||||
|
Seiji Takahashi <timaki.st@gmail.com>
|
||||||
Sergei Skorobogatov <skorobo@rambler.ru>
|
Sergei Skorobogatov <skorobo@rambler.ru>
|
||||||
Sergey 'SnakE' Gromov <snake.scaly@gmail.com>
|
Sergey 'SnakE' Gromov <snake.scaly@gmail.com>
|
||||||
Sergey Mishin <sergeymishine@gmail.com>
|
Sergey Mishin <sergeymishine@gmail.com>
|
||||||
|
Sergey Semin <gray12511@gmail.com>
|
||||||
Sergio Luis O. B. Correia <sergio@correia.cc>
|
Sergio Luis O. B. Correia <sergio@correia.cc>
|
||||||
|
Sergiusz Bazanski <bazanski@gmail.com>
|
||||||
Seth Hoenig <seth.a.hoenig@gmail.com>
|
Seth Hoenig <seth.a.hoenig@gmail.com>
|
||||||
Seth Vargo <sethvargo@gmail.com>
|
Seth Vargo <sethvargo@gmail.com>
|
||||||
Shahar Kohanim <skohanim@gmail.com>
|
Shahar Kohanim <skohanim@gmail.com>
|
||||||
|
|
@ -968,11 +1096,13 @@ Square, Inc.
|
||||||
Sridhar Venkatakrishnan <sridhar@laddoo.net>
|
Sridhar Venkatakrishnan <sridhar@laddoo.net>
|
||||||
StalkR <stalkr@stalkr.net>
|
StalkR <stalkr@stalkr.net>
|
||||||
Stan Schwertly <stan@schwertly.com>
|
Stan Schwertly <stan@schwertly.com>
|
||||||
|
Stanislav Afanasev <php.progger@gmail.com>
|
||||||
Stefan Nilsson <snilsson@nada.kth.se> <trolleriprofessorn@gmail.com>
|
Stefan Nilsson <snilsson@nada.kth.se> <trolleriprofessorn@gmail.com>
|
||||||
Stéphane Travostino <stephane.travostino@gmail.com>
|
Stéphane Travostino <stephane.travostino@gmail.com>
|
||||||
Stephen McQuay <stephen@mcquay.me>
|
Stephen McQuay <stephen@mcquay.me>
|
||||||
Stephen Searles <stephens2424@gmail.com>
|
Stephen Searles <stephens2424@gmail.com>
|
||||||
Stephen Weinberg <stephen@q5comm.com>
|
Stephen Weinberg <stephen@q5comm.com>
|
||||||
|
Steve Gilbert <stevegilbert23@gmail.com>
|
||||||
Steve McCoy <mccoyst@gmail.com>
|
Steve McCoy <mccoyst@gmail.com>
|
||||||
Steve Phillips <elimisteve@gmail.com>
|
Steve Phillips <elimisteve@gmail.com>
|
||||||
Steve Streeting <steve@stevestreeting.com>
|
Steve Streeting <steve@stevestreeting.com>
|
||||||
|
|
@ -981,46 +1111,57 @@ Steven Erenst <stevenerenst@gmail.com>
|
||||||
Steven Hartland <steven.hartland@multiplay.co.uk>
|
Steven Hartland <steven.hartland@multiplay.co.uk>
|
||||||
Steven Wilkin <stevenwilkin@gmail.com>
|
Steven Wilkin <stevenwilkin@gmail.com>
|
||||||
Stripe, Inc.
|
Stripe, Inc.
|
||||||
|
Sukrit Handa <sukrit.handa@utoronto.ca>
|
||||||
Sunny <me@darkowlzz.space>
|
Sunny <me@darkowlzz.space>
|
||||||
Suyash <dextrous93@gmail.com>
|
Suyash <dextrous93@gmail.com>
|
||||||
Sven Almgren <sven@tras.se>
|
Sven Almgren <sven@tras.se>
|
||||||
|
Sylvain Zimmer <sylvain@sylvainzimmer.com>
|
||||||
Syohei YOSHIDA <syohex@gmail.com>
|
Syohei YOSHIDA <syohex@gmail.com>
|
||||||
Szabolcs Nagy <nsz@port70.net>
|
Szabolcs Nagy <nsz@port70.net>
|
||||||
|
Tad Fisher <tadfisher@gmail.com>
|
||||||
Tad Glines <tad.glines@gmail.com>
|
Tad Glines <tad.glines@gmail.com>
|
||||||
Taj Khattra <taj.khattra@gmail.com>
|
Taj Khattra <taj.khattra@gmail.com>
|
||||||
Takeshi YAMANASHI <9.nashi@gmail.com>
|
Takeshi YAMANASHI <9.nashi@gmail.com>
|
||||||
Takuya Ueda <uedatakuya@gmail.com>
|
Takuya Ueda <uedatakuya@gmail.com>
|
||||||
Tal Shprecher <tshprecher@gmail.com>
|
Tal Shprecher <tshprecher@gmail.com>
|
||||||
Tamir Duberstein <tamird@gmail.com>
|
Tamir Duberstein <tamird@gmail.com>
|
||||||
|
Tao Wang <twang2218@gmail.com>
|
||||||
Tarmigan Casebolt <tarmigan@gmail.com>
|
Tarmigan Casebolt <tarmigan@gmail.com>
|
||||||
Taro Aoki <aizu.s1230022@gmail.com>
|
Taro Aoki <aizu.s1230022@gmail.com>
|
||||||
Taru Karttunen <taruti@taruti.net>
|
Taru Karttunen <taruti@taruti.net>
|
||||||
Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
|
Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
|
||||||
Ted Kornish <golang@tedkornish.com>
|
Ted Kornish <golang@tedkornish.com>
|
||||||
Teleport Inc.
|
Teleport Inc.
|
||||||
|
Terin Stock <terinjokes@gmail.com>
|
||||||
Terrel Shumway <gopher@shumway.us>
|
Terrel Shumway <gopher@shumway.us>
|
||||||
Tetsuo Kiso <tetsuokiso9@gmail.com>
|
Tetsuo Kiso <tetsuokiso9@gmail.com>
|
||||||
Thanatat Tamtan <acoshift@gmail.com>
|
Thanatat Tamtan <acoshift@gmail.com>
|
||||||
|
Thiago Avelino <t@avelino.xxx>
|
||||||
Thiago Fransosi Farina <thiago.farina@gmail.com>
|
Thiago Fransosi Farina <thiago.farina@gmail.com>
|
||||||
Thomas Alan Copeland <talan.copeland@gmail.com>
|
Thomas Alan Copeland <talan.copeland@gmail.com>
|
||||||
Thomas Bonfort <thomas.bonfort@gmail.com>
|
Thomas Bonfort <thomas.bonfort@gmail.com>
|
||||||
Thomas de Zeeuw <thomasdezeeuw@gmail.com>
|
Thomas de Zeeuw <thomasdezeeuw@gmail.com>
|
||||||
Thomas Desrosiers <thomasdesr@gmail.com>
|
Thomas Desrosiers <thomasdesr@gmail.com>
|
||||||
Thomas Kappler <tkappler@gmail.com>
|
Thomas Kappler <tkappler@gmail.com>
|
||||||
|
Thomas Wanielista <tomwans@gmail.com>
|
||||||
Thorben Krueger <thorben.krueger@gmail.com>
|
Thorben Krueger <thorben.krueger@gmail.com>
|
||||||
Thordur Bjornsson <thorduri@secnorth.net>
|
Thordur Bjornsson <thorduri@secnorth.net>
|
||||||
Tilman Dilo <tilman.dilo@gmail.com>
|
Tilman Dilo <tilman.dilo@gmail.com>
|
||||||
Tim Cooijmans <timcooijmans@gmail.com>
|
Tim Cooijmans <timcooijmans@gmail.com>
|
||||||
|
Tim Cooper <tim.cooper@layeh.com>
|
||||||
Tim Ebringer <tim.ebringer@gmail.com>
|
Tim Ebringer <tim.ebringer@gmail.com>
|
||||||
Tim Heckman <t@heckman.io>
|
Tim Heckman <t@heckman.io>
|
||||||
Tim Henderson <tim.tadh@gmail.com>
|
Tim Henderson <tim.tadh@gmail.com>
|
||||||
|
Tim Wright <tenortim@gmail.com>
|
||||||
Timo Savola <timo.savola@gmail.com>
|
Timo Savola <timo.savola@gmail.com>
|
||||||
Timo Truyts <alkaloid.btx@gmail.com>
|
Timo Truyts <alkaloid.btx@gmail.com>
|
||||||
Timothy Studd <tim@timstudd.com>
|
Timothy Studd <tim@timstudd.com>
|
||||||
|
Tobias Assarsson <tobias.assarsson@gmail.com>
|
||||||
Tobias Columbus <tobias.columbus@gmail.com>
|
Tobias Columbus <tobias.columbus@gmail.com>
|
||||||
Tobias Klauser <tklauser@distanz.ch>
|
Tobias Klauser <tklauser@distanz.ch>
|
||||||
Todd Neal <todd@tneal.org>
|
Todd Neal <todd@tneal.org>
|
||||||
Tom Heng <zhm20070928@gmail.com>
|
Tom Heng <zhm20070928@gmail.com>
|
||||||
|
Tom Levy <tomlevy93@gmail.com>
|
||||||
Tom Linford <tomlinford@gmail.com>
|
Tom Linford <tomlinford@gmail.com>
|
||||||
Tommy Schaefer <tommy.schaefer@teecom.com>
|
Tommy Schaefer <tommy.schaefer@teecom.com>
|
||||||
Tonis Tiigi <tonistiigi@gmail.com>
|
Tonis Tiigi <tonistiigi@gmail.com>
|
||||||
|
|
@ -1035,8 +1176,10 @@ Trey Roessig <trey.roessig@gmail.com>
|
||||||
Trey Tacon <ttacon@gmail.com>
|
Trey Tacon <ttacon@gmail.com>
|
||||||
Tristan Colgate <tcolgate@gmail.com>
|
Tristan Colgate <tcolgate@gmail.com>
|
||||||
Tristan Ooohry <ooohry@gmail.com>
|
Tristan Ooohry <ooohry@gmail.com>
|
||||||
|
Troels Thomsen <troels@thomsen.io>
|
||||||
Trung Nguyen <trung.n.k@gmail.com>
|
Trung Nguyen <trung.n.k@gmail.com>
|
||||||
Tudor Golubenco <tudor.g@gmail.com>
|
Tudor Golubenco <tudor.g@gmail.com>
|
||||||
|
Tugdual Saunier <tugdual.saunier@gmail.com>
|
||||||
Tuo Shan <sturbo89@gmail.com>
|
Tuo Shan <sturbo89@gmail.com>
|
||||||
Tyler Bunnell <tylerbunnell@gmail.com>
|
Tyler Bunnell <tylerbunnell@gmail.com>
|
||||||
Tyler Treat <ttreat31@gmail.com>
|
Tyler Treat <ttreat31@gmail.com>
|
||||||
|
|
@ -1063,14 +1206,18 @@ Volker Dobler <dr.volker.dobler@gmail.com>
|
||||||
Wade Simmons <wade@wades.im>
|
Wade Simmons <wade@wades.im>
|
||||||
Wander Lairson Costa <wcosta@mozilla.com>
|
Wander Lairson Costa <wcosta@mozilla.com>
|
||||||
Weaveworks
|
Weaveworks
|
||||||
|
Wèi Cōngruì <crvv.mail@gmail.com>
|
||||||
Wei Guangjing <vcc.163@gmail.com>
|
Wei Guangjing <vcc.163@gmail.com>
|
||||||
Weichao Tang <tevic.tt@gmail.com>
|
Weichao Tang <tevic.tt@gmail.com>
|
||||||
|
Wembley G. Leach, Jr <wembley.gl@gmail.com>
|
||||||
|
Will Faught <will.faught@gmail.com>
|
||||||
Will Storey <will@summercat.com>
|
Will Storey <will@summercat.com>
|
||||||
Willem van der Schyff <willemvds@gmail.com>
|
Willem van der Schyff <willemvds@gmail.com>
|
||||||
William Josephson <wjosephson@gmail.com>
|
William Josephson <wjosephson@gmail.com>
|
||||||
William Orr <will@worrbase.com> <ay1244@gmail.com>
|
William Orr <will@worrbase.com> <ay1244@gmail.com>
|
||||||
Wisdom Omuya <deafgoat@gmail.com>
|
Wisdom Omuya <deafgoat@gmail.com>
|
||||||
Wu Yunzhou <yunzhouwu@gmail.com>
|
Wu Yunzhou <yunzhouwu@gmail.com>
|
||||||
|
Xi Ruoyao <xry23333@gmail.com>
|
||||||
Xia Bin <snyh@snyh.org>
|
Xia Bin <snyh@snyh.org>
|
||||||
Xing Xing <mikespook@gmail.com>
|
Xing Xing <mikespook@gmail.com>
|
||||||
Xu Fei <badgangkiller@gmail.com>
|
Xu Fei <badgangkiller@gmail.com>
|
||||||
|
|
@ -1078,30 +1225,36 @@ Xudong Zhang <felixmelon@gmail.com>
|
||||||
Xuyang Kang <xuyangkang@gmail.com>
|
Xuyang Kang <xuyangkang@gmail.com>
|
||||||
Yahoo Inc.
|
Yahoo Inc.
|
||||||
Yann Kerhervé <yann.kerherve@gmail.com>
|
Yann Kerhervé <yann.kerherve@gmail.com>
|
||||||
|
Yann Salaün <yannsalaun1@gmail.com>
|
||||||
Yao Zhang <lunaria21@gmail.com>
|
Yao Zhang <lunaria21@gmail.com>
|
||||||
Yasha Bubnov <girokompass@gmail.com>
|
Yasha Bubnov <girokompass@gmail.com>
|
||||||
Yasuharu Goto <matope.ono@gmail.com>
|
Yasuharu Goto <matope.ono@gmail.com>
|
||||||
Yasuhiro Matsumoto <mattn.jp@gmail.com>
|
Yasuhiro Matsumoto <mattn.jp@gmail.com>
|
||||||
Yestin Sun <ylh@pdx.edu>
|
Yestin Sun <ylh@pdx.edu>
|
||||||
Yesudeep Mangalapilly <yesudeep@google.com>
|
|
||||||
Yissakhar Z. Beck <yissakhar.beck@gmail.com>
|
Yissakhar Z. Beck <yissakhar.beck@gmail.com>
|
||||||
Yo-An Lin <yoanlin93@gmail.com>
|
Yo-An Lin <yoanlin93@gmail.com>
|
||||||
Yongjian Xu <i3dmaster@gmail.com>
|
Yongjian Xu <i3dmaster@gmail.com>
|
||||||
Yorman Arias <cixtords@gmail.com>
|
Yorman Arias <cixtords@gmail.com>
|
||||||
Yoshiyuki Kanno <nekotaroh@gmail.com> <yoshiyuki.kanno@stoic.co.jp>
|
Yoshiyuki Kanno <nekotaroh@gmail.com> <yoshiyuki.kanno@stoic.co.jp>
|
||||||
|
Yosuke Akatsuka <yosuke.akatsuka@gmail.com>
|
||||||
|
Yukihiro Nishinaka <6elpinal@gmail.com>
|
||||||
Yusuke Kagiwada <block.rxckin.beats@gmail.com>
|
Yusuke Kagiwada <block.rxckin.beats@gmail.com>
|
||||||
Yuusei Kuwana <kuwana@kumama.org>
|
Yuusei Kuwana <kuwana@kumama.org>
|
||||||
Yuval Pavel Zholkover <paulzhol@gmail.com>
|
Yuval Pavel Zholkover <paulzhol@gmail.com>
|
||||||
Zac Bergquist <zbergquist99@gmail.com>
|
Zac Bergquist <zbergquist99@gmail.com>
|
||||||
Zach Bintliff <zbintliff@gmail.com>
|
Zach Bintliff <zbintliff@gmail.com>
|
||||||
|
Zach Gershman <zachgersh@gmail.com>
|
||||||
Zak <zrjknill@gmail.com>
|
Zak <zrjknill@gmail.com>
|
||||||
Zakatell Kanda <hi@zkanda.io>
|
Zakatell Kanda <hi@zkanda.io>
|
||||||
Zellyn Hunter <zellyn@gmail.com>
|
Zellyn Hunter <zellyn@gmail.com>
|
||||||
Zemanta d.o.o.
|
Zemanta d.o.o.
|
||||||
Zev Goldstein <zev.goldstein@gmail.com>
|
Zev Goldstein <zev.goldstein@gmail.com>
|
||||||
|
Zhongtao Chen <chenzhongtao@126.com>
|
||||||
Ziad Hatahet <hatahet@gmail.com>
|
Ziad Hatahet <hatahet@gmail.com>
|
||||||
Zorion Arrizabalaga <zorionk@gmail.com>
|
Zorion Arrizabalaga <zorionk@gmail.com>
|
||||||
Максим Федосеев <max.faceless.frei@gmail.com>
|
Максим Федосеев <max.faceless.frei@gmail.com>
|
||||||
|
Роман Хавроненко <hagen1778@gmail.com>
|
||||||
|
Тарас Буник <tbunyk@gmail.com>
|
||||||
Фахриддин Балтаев <faxriddinjon@gmail.com>
|
Фахриддин Балтаев <faxriddinjon@gmail.com>
|
||||||
张嵩 <zs349596@gmail.com>
|
张嵩 <zs349596@gmail.com>
|
||||||
申习之 <bronze1man@gmail.com>
|
申习之 <bronze1man@gmail.com>
|
||||||
|
|
|
||||||
|
|
@ -30,11 +30,6 @@ For change proposals, see [Proposing Changes To Go](https://github.com/golang/pr
|
||||||
|
|
||||||
Please read the [Contribution Guidelines](https://golang.org/doc/contribute.html) before sending patches.
|
Please read the [Contribution Guidelines](https://golang.org/doc/contribute.html) before sending patches.
|
||||||
|
|
||||||
**We do not accept GitHub pull requests**
|
|
||||||
(we use [an instance](https://go-review.googlesource.com/) of the
|
|
||||||
[Gerrit](https://www.gerritcodereview.com/) code review system instead).
|
|
||||||
Also, please do not post patches on the issue tracker.
|
|
||||||
|
|
||||||
Unless otherwise noted, the Go source files are distributed under
|
Unless otherwise noted, the Go source files are distributed under
|
||||||
the BSD-style license found in the LICENSE file.
|
the BSD-style license found in the LICENSE file.
|
||||||
|
|
||||||
|
|
|
||||||
175
CONTRIBUTORS
175
CONTRIBUTORS
|
|
@ -44,13 +44,18 @@ Adam Bender <abender@google.com>
|
||||||
Adam Eijdenberg <adam@continusec.com>
|
Adam Eijdenberg <adam@continusec.com>
|
||||||
Adam Kisala <adam.kisala@gmail.com>
|
Adam Kisala <adam.kisala@gmail.com>
|
||||||
Adam Langley <agl@golang.org>
|
Adam Langley <agl@golang.org>
|
||||||
|
Adam Thomason <athomason@gmail.com>
|
||||||
Aditya Mukerjee <dev@chimeracoder.net>
|
Aditya Mukerjee <dev@chimeracoder.net>
|
||||||
|
Adrian Hesketh <adrianhesketh@hushmail.com>
|
||||||
Adrian Nos <nos.adrian@gmail.com>
|
Adrian Nos <nos.adrian@gmail.com>
|
||||||
Adrian O'Grady <elpollouk@gmail.com>
|
Adrian O'Grady <elpollouk@gmail.com>
|
||||||
Adrien Bustany <adrien-xx-google@bustany.org>
|
Adrien Bustany <adrien-xx-google@bustany.org>
|
||||||
Aécio Júnior <aeciodantasjunior@gmail.com>
|
Aécio Júnior <aeciodantasjunior@gmail.com>
|
||||||
|
Aeneas Rekkas (arekkas) <aeneas@ory.am>
|
||||||
|
Afanasev Stanislav <phpprogger@gmail.com>
|
||||||
Agis Anastasopoulos <agis.anast@gmail.com>
|
Agis Anastasopoulos <agis.anast@gmail.com>
|
||||||
Ahmed Waheed Moanes <oneofone@gmail.com>
|
Agniva De Sarker <agnivade@yahoo.co.in>
|
||||||
|
Ahmed Wahed <oneofone@gmail.com>
|
||||||
Ahmet Alp Balkan <ahmetb@google.com>
|
Ahmet Alp Balkan <ahmetb@google.com>
|
||||||
Ahmy Yulrizka <yulrizka@gmail.com>
|
Ahmy Yulrizka <yulrizka@gmail.com>
|
||||||
Aiden Scandella <ai@uber.com>
|
Aiden Scandella <ai@uber.com>
|
||||||
|
|
@ -90,6 +95,7 @@ Alexander Menzhinsky <amenzhinsky@gmail.com>
|
||||||
Alexander Morozov <lk4d4math@gmail.com>
|
Alexander Morozov <lk4d4math@gmail.com>
|
||||||
Alexander Neumann <alexander@bumpern.de>
|
Alexander Neumann <alexander@bumpern.de>
|
||||||
Alexander Orlov <alexander.orlov@loxal.net>
|
Alexander Orlov <alexander.orlov@loxal.net>
|
||||||
|
Alexander Pantyukhin <apantykhin@gmail.com>
|
||||||
Alexander Polcyn <apolcyn@google.com>
|
Alexander Polcyn <apolcyn@google.com>
|
||||||
Alexander Reece <awreece@gmail.com>
|
Alexander Reece <awreece@gmail.com>
|
||||||
Alexander Surma <surma@surmair.de>
|
Alexander Surma <surma@surmair.de>
|
||||||
|
|
@ -98,6 +104,7 @@ Alexander Zolotov <goldifit@gmail.com>
|
||||||
Alexandre Cesaro <alexandre.cesaro@gmail.com>
|
Alexandre Cesaro <alexandre.cesaro@gmail.com>
|
||||||
Alexandre Fiori <fiorix@gmail.com>
|
Alexandre Fiori <fiorix@gmail.com>
|
||||||
Alexandre Normand <alexandre.normand@gmail.com>
|
Alexandre Normand <alexandre.normand@gmail.com>
|
||||||
|
Alexandre Parentea <aubonbeurre@gmail.com>
|
||||||
Alexandru Moșoi <brtzsnr@gmail.com>
|
Alexandru Moșoi <brtzsnr@gmail.com>
|
||||||
Alexei Sholik <alcosholik@gmail.com>
|
Alexei Sholik <alcosholik@gmail.com>
|
||||||
Alexey Borzenkov <snaury@gmail.com>
|
Alexey Borzenkov <snaury@gmail.com>
|
||||||
|
|
@ -110,8 +117,10 @@ Aliaksandr Valialkin <valyala@gmail.com>
|
||||||
Alif Rachmawadi <subosito@gmail.com>
|
Alif Rachmawadi <subosito@gmail.com>
|
||||||
Allan Simon <allan.simon@supinfo.com>
|
Allan Simon <allan.simon@supinfo.com>
|
||||||
Alok Menghrajani <alok.menghrajani@gmail.com>
|
Alok Menghrajani <alok.menghrajani@gmail.com>
|
||||||
|
Aman Gupta <aman@tmm1.net>
|
||||||
Amir Mohammad Saied <amir@gluegadget.com>
|
Amir Mohammad Saied <amir@gluegadget.com>
|
||||||
Amrut Joshi <amrut.joshi@gmail.com>
|
Amrut Joshi <amrut.joshi@gmail.com>
|
||||||
|
Anand K. Mistry <anand@mistry.ninja>
|
||||||
Anders Pearson <anders@columbia.edu>
|
Anders Pearson <anders@columbia.edu>
|
||||||
André Carvalho <asantostc@gmail.com>
|
André Carvalho <asantostc@gmail.com>
|
||||||
Andre Nathan <andrenth@gmail.com>
|
Andre Nathan <andrenth@gmail.com>
|
||||||
|
|
@ -144,7 +153,10 @@ Andrew Wilkins <axwalk@gmail.com>
|
||||||
Andrew Williams <williams.andrew@gmail.com>
|
Andrew Williams <williams.andrew@gmail.com>
|
||||||
Andrey Mirtchovski <mirtchovski@gmail.com>
|
Andrey Mirtchovski <mirtchovski@gmail.com>
|
||||||
Andrey Petrov <andrey.petrov@shazow.net>
|
Andrey Petrov <andrey.petrov@shazow.net>
|
||||||
|
Andrii Soldatenko <andrii.soldatenko@gmail.com>
|
||||||
|
Andrii Soluk <isoluchok@gmail.com>
|
||||||
Andriy Lytvynov <lytvynov.a.v@gmail.com>
|
Andriy Lytvynov <lytvynov.a.v@gmail.com>
|
||||||
|
Andrzej Żeżel <andrii.zhezhel@gmail.com>
|
||||||
Andy Balholm <andy@balholm.com>
|
Andy Balholm <andy@balholm.com>
|
||||||
Andy Davis <andy@bigandian.com>
|
Andy Davis <andy@bigandian.com>
|
||||||
Andy Finkenstadt <afinkenstadt@zynga.com>
|
Andy Finkenstadt <afinkenstadt@zynga.com>
|
||||||
|
|
@ -155,9 +167,11 @@ Angelo Bulfone <mbulfone@gmail.com>
|
||||||
Anh Hai Trinh <anh.hai.trinh@gmail.com>
|
Anh Hai Trinh <anh.hai.trinh@gmail.com>
|
||||||
Anmol Sethi <anmol@aubble.com>
|
Anmol Sethi <anmol@aubble.com>
|
||||||
Anschel Schaffer-Cohen <anschelsc@gmail.com>
|
Anschel Schaffer-Cohen <anschelsc@gmail.com>
|
||||||
|
Anthony Alves <cvballa3g0@gmail.com>
|
||||||
Anthony Canino <anthony.canino1@gmail.com>
|
Anthony Canino <anthony.canino1@gmail.com>
|
||||||
Anthony Eufemio <anthony.eufemio@gmail.com>
|
Anthony Eufemio <anthony.eufemio@gmail.com>
|
||||||
Anthony Martin <ality@pbrane.org>
|
Anthony Martin <ality@pbrane.org>
|
||||||
|
Anthony Sottile <asottile@umich.edu>
|
||||||
Anthony Starks <ajstarks@gmail.com>
|
Anthony Starks <ajstarks@gmail.com>
|
||||||
Anthony Voutas <voutasaurus@gmail.com>
|
Anthony Voutas <voutasaurus@gmail.com>
|
||||||
Anthony Woods <awoods@raintank.io>
|
Anthony Woods <awoods@raintank.io>
|
||||||
|
|
@ -168,6 +182,7 @@ Antonio Troina <thoeni@gmail.com>
|
||||||
Apisak Darakananda <pongad@gmail.com>
|
Apisak Darakananda <pongad@gmail.com>
|
||||||
Aram Hăvărneanu <aram@mgk.ro>
|
Aram Hăvărneanu <aram@mgk.ro>
|
||||||
Areski Belaid <areski@gmail.com>
|
Areski Belaid <areski@gmail.com>
|
||||||
|
Ariel Mashraki <ariel@mashraki.co.il>
|
||||||
Arkadi Pyuro <arkadi@google.com>
|
Arkadi Pyuro <arkadi@google.com>
|
||||||
Arlo Breault <arlolra@gmail.com>
|
Arlo Breault <arlolra@gmail.com>
|
||||||
Arnaud Ysmal <arnaud.ysmal@gmail.com>
|
Arnaud Ysmal <arnaud.ysmal@gmail.com>
|
||||||
|
|
@ -185,6 +200,7 @@ Aulus Egnatius Varialus <varialus@gmail.com>
|
||||||
Austin Clements <austin@google.com> <aclements@csail.mit.edu>
|
Austin Clements <austin@google.com> <aclements@csail.mit.edu>
|
||||||
awaw fumin <awawfumin@gmail.com>
|
awaw fumin <awawfumin@gmail.com>
|
||||||
Awn Umar <awn@cryptolosophy.io>
|
Awn Umar <awn@cryptolosophy.io>
|
||||||
|
Axel Wagner <axel.wagner.hh@googlemail.com>
|
||||||
Ayanamist Yang <ayanamist@gmail.com>
|
Ayanamist Yang <ayanamist@gmail.com>
|
||||||
Aymerick Jéhanne <aymerick@jehanne.org>
|
Aymerick Jéhanne <aymerick@jehanne.org>
|
||||||
Baiju Muthukadan <baiju.m.mail@gmail.com>
|
Baiju Muthukadan <baiju.m.mail@gmail.com>
|
||||||
|
|
@ -194,9 +210,12 @@ Bastian Ike <bastian.ike@gmail.com>
|
||||||
Ben Burkert <ben@benburkert.com>
|
Ben Burkert <ben@benburkert.com>
|
||||||
Ben Eitzen <eitzenb@golang.org>
|
Ben Eitzen <eitzenb@golang.org>
|
||||||
Ben Fried <ben.fried@gmail.com>
|
Ben Fried <ben.fried@gmail.com>
|
||||||
|
Ben Haines <bhainesva@gmail.com>
|
||||||
|
Ben Laurie <ben@links.org> <benl@google.com>
|
||||||
Ben Lubar <ben.lubar@gmail.com>
|
Ben Lubar <ben.lubar@gmail.com>
|
||||||
Ben Lynn <benlynn@gmail.com>
|
Ben Lynn <benlynn@gmail.com>
|
||||||
Ben Olive <sionide21@gmail.com>
|
Ben Olive <sionide21@gmail.com>
|
||||||
|
Ben Schwartz <bemasc@google.com>
|
||||||
Ben Shi <powerman1st@163.com>
|
Ben Shi <powerman1st@163.com>
|
||||||
Benjamin Black <b@b3k.us>
|
Benjamin Black <b@b3k.us>
|
||||||
Benjamin Prosnitz <bprosnitz@google.com>
|
Benjamin Prosnitz <bprosnitz@google.com>
|
||||||
|
|
@ -212,11 +231,15 @@ Billie Harold Cleek <bhcleek@gmail.com>
|
||||||
Billy Lynch <wlynch@google.com>
|
Billy Lynch <wlynch@google.com>
|
||||||
Bjorn Tillenius <bjorn@tillenius.me>
|
Bjorn Tillenius <bjorn@tillenius.me>
|
||||||
Bjorn Tipling <bjorn.tipling@gmail.com>
|
Bjorn Tipling <bjorn.tipling@gmail.com>
|
||||||
|
Blain Smith <rebelgeek@blainsmith.com>
|
||||||
Blake Gentry <blakesgentry@gmail.com>
|
Blake Gentry <blakesgentry@gmail.com>
|
||||||
|
Blake Mesdag <blakemesdag@gmail.com>
|
||||||
Blake Mizerany <blake.mizerany@gmail.com>
|
Blake Mizerany <blake.mizerany@gmail.com>
|
||||||
Blixt <me@blixt.nyc>
|
Blixt <me@blixt.nyc>
|
||||||
Bobby Powers <bobbypowers@gmail.com>
|
Bobby Powers <bobbypowers@gmail.com>
|
||||||
Boris Nagaev <nagaev@google.com>
|
Boris Nagaev <nagaev@google.com>
|
||||||
|
Borja Clemente <borja.clemente@gmail.com>
|
||||||
|
Brad Burch <brad.burch@gmail.com>
|
||||||
Brad Fitzpatrick <bradfitz@golang.org> <bradfitz@gmail.com>
|
Brad Fitzpatrick <bradfitz@golang.org> <bradfitz@gmail.com>
|
||||||
Brad Garcia <bgarcia@golang.org>
|
Brad Garcia <bgarcia@golang.org>
|
||||||
Brad Jones <rbjones@google.com>
|
Brad Jones <rbjones@google.com>
|
||||||
|
|
@ -229,11 +252,13 @@ Brandon Gilmore <varz@google.com>
|
||||||
Brendan Daniel Tracey <tracey.brendan@gmail.com>
|
Brendan Daniel Tracey <tracey.brendan@gmail.com>
|
||||||
Brendan O'Dea <bod@golang.org>
|
Brendan O'Dea <bod@golang.org>
|
||||||
Brett Cannon <bcannon@gmail.com>
|
Brett Cannon <bcannon@gmail.com>
|
||||||
|
Brett Merrill <brett.j.merrill94@gmail.com>
|
||||||
Brian Dellisanti <briandellisanti@gmail.com>
|
Brian Dellisanti <briandellisanti@gmail.com>
|
||||||
Brian Downs <brian.downs@gmail.com>
|
Brian Downs <brian.downs@gmail.com>
|
||||||
Brian G. Merrell <bgmerrell@gmail.com>
|
Brian G. Merrell <bgmerrell@gmail.com>
|
||||||
Brian Gitonga Marete <marete@toshnix.com> <bgmarete@gmail.com> <bgm@google.com>
|
Brian Gitonga Marete <marete@toshnix.com> <bgmarete@gmail.com> <bgm@google.com>
|
||||||
Brian Kennedy <btkennedy@gmail.com>
|
Brian Kennedy <btkennedy@gmail.com>
|
||||||
|
Brian Kessler <brian.m.kessler@gmail.com>
|
||||||
Brian Ketelsen <bketelsen@gmail.com>
|
Brian Ketelsen <bketelsen@gmail.com>
|
||||||
Brian Slesinsky <skybrian@google.com>
|
Brian Slesinsky <skybrian@google.com>
|
||||||
Brian Smith <ohohvi@gmail.com>
|
Brian Smith <ohohvi@gmail.com>
|
||||||
|
|
@ -243,6 +268,7 @@ Bryan C. Mills <bcmills@google.com>
|
||||||
Bryan Chan <bryan.chan@ca.ibm.com>
|
Bryan Chan <bryan.chan@ca.ibm.com>
|
||||||
Bryan Ford <brynosaurus@gmail.com>
|
Bryan Ford <brynosaurus@gmail.com>
|
||||||
Bulat Gaifullin <gaifullinbf@gmail.com>
|
Bulat Gaifullin <gaifullinbf@gmail.com>
|
||||||
|
Burak Guven <bguven@gmail.com>
|
||||||
Caine Tighe <arctanofyourface@gmail.com>
|
Caine Tighe <arctanofyourface@gmail.com>
|
||||||
Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
|
Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
|
||||||
Caleb Spare <cespare@gmail.com>
|
Caleb Spare <cespare@gmail.com>
|
||||||
|
|
@ -266,11 +292,14 @@ Catalin Patulea <catalinp@google.com>
|
||||||
Cedric Staub <cs@squareup.com>
|
Cedric Staub <cs@squareup.com>
|
||||||
Cezar Sá Espinola <cezarsa@gmail.com>
|
Cezar Sá Espinola <cezarsa@gmail.com>
|
||||||
ChaiShushan <chaishushan@gmail.com>
|
ChaiShushan <chaishushan@gmail.com>
|
||||||
|
Charles Fenwick Elliott <Charles@FenwickElliott.io>
|
||||||
Charles L. Dorian <cldorian@gmail.com>
|
Charles L. Dorian <cldorian@gmail.com>
|
||||||
Charles Lee <zombie.fml@gmail.com>
|
Charles Lee <zombie.fml@gmail.com>
|
||||||
Charles Weill <weill@google.com>
|
Charles Weill <weill@google.com>
|
||||||
Cherry Zhang <cherryyz@google.com>
|
Cherry Zhang <cherryyz@google.com>
|
||||||
Chew Choon Keat <choonkeat@gmail.com>
|
Chew Choon Keat <choonkeat@gmail.com>
|
||||||
|
Cholerae Hu <choleraehyq@gmail.com>
|
||||||
|
Chris Ball <chris@printf.net>
|
||||||
Chris Biscardi <chris@christopherbiscardi.com>
|
Chris Biscardi <chris@christopherbiscardi.com>
|
||||||
Chris Broadfoot <cbro@golang.org>
|
Chris Broadfoot <cbro@golang.org>
|
||||||
Chris Dollin <ehog.hedge@gmail.com>
|
Chris Dollin <ehog.hedge@gmail.com>
|
||||||
|
|
@ -287,6 +316,7 @@ Chris Raynor <raynor@google.com>
|
||||||
Chris Roche <rodaine@gmail.com>
|
Chris Roche <rodaine@gmail.com>
|
||||||
Chris Stockton <chrisstocktonaz@gmail.com>
|
Chris Stockton <chrisstocktonaz@gmail.com>
|
||||||
Chris Zou <chriszou@ca.ibm.com>
|
Chris Zou <chriszou@ca.ibm.com>
|
||||||
|
Christian Alexander <christian@linux.com>
|
||||||
Christian Couder <chriscool@tuxfamily.org>
|
Christian Couder <chriscool@tuxfamily.org>
|
||||||
Christian Himpel <chressie@googlemail.com> <chressie@gmail.com>
|
Christian Himpel <chressie@googlemail.com> <chressie@gmail.com>
|
||||||
Christine Hansmann <chhansmann@gmail.com>
|
Christine Hansmann <chhansmann@gmail.com>
|
||||||
|
|
@ -294,11 +324,14 @@ Christoffer Buchholz <christoffer.buchholz@gmail.com>
|
||||||
Christoph Hack <christoph@tux21b.org>
|
Christoph Hack <christoph@tux21b.org>
|
||||||
Christopher Cahoon <chris.cahoon@gmail.com>
|
Christopher Cahoon <chris.cahoon@gmail.com>
|
||||||
Christopher Guiney <chris@guiney.net>
|
Christopher Guiney <chris@guiney.net>
|
||||||
|
Christopher Henderson <chris@chenderson.org>
|
||||||
|
Christopher Koch <chrisko@google.com>
|
||||||
Christopher Nelson <nadiasvertex@gmail.com>
|
Christopher Nelson <nadiasvertex@gmail.com>
|
||||||
Christopher Nielsen <m4dh4tt3r@gmail.com>
|
Christopher Nielsen <m4dh4tt3r@gmail.com>
|
||||||
Christopher Redden <christopher.redden@gmail.com>
|
Christopher Redden <christopher.redden@gmail.com>
|
||||||
Christopher Swenson <cswenson@google.com>
|
Christopher Swenson <cswenson@google.com>
|
||||||
Christopher Wedgwood <cw@f00f.org>
|
Christopher Wedgwood <cw@f00f.org>
|
||||||
|
Christos Zoulas <christos@zoulas.com> <zoulasc@gmail.com>
|
||||||
Christy Perez <christy@linux.vnet.ibm.com>
|
Christy Perez <christy@linux.vnet.ibm.com>
|
||||||
CL Sung <clsung@gmail.com> <cl_sung@htc.com>
|
CL Sung <clsung@gmail.com> <cl_sung@htc.com>
|
||||||
Clement Skau <clementskau@gmail.com>
|
Clement Skau <clementskau@gmail.com>
|
||||||
|
|
@ -341,6 +374,8 @@ Daniel Skinner <daniel@dasa.cc>
|
||||||
Daniel Speichert <daniel@speichert.pl>
|
Daniel Speichert <daniel@speichert.pl>
|
||||||
Daniel Theophanes <kardianos@gmail.com>
|
Daniel Theophanes <kardianos@gmail.com>
|
||||||
Daniel Upton <daniel@floppy.co>
|
Daniel Upton <daniel@floppy.co>
|
||||||
|
Daniela Petruzalek <daniela.petruzalek@gmail.com>
|
||||||
|
Danny Rosseau <daniel.rosseau@gmail.com>
|
||||||
Daria Kolistratova <daria.kolistratova@intel.com>
|
Daria Kolistratova <daria.kolistratova@intel.com>
|
||||||
Darren Elwood <darren@textnode.com>
|
Darren Elwood <darren@textnode.com>
|
||||||
Datong Sun <dndx@idndx.com>
|
Datong Sun <dndx@idndx.com>
|
||||||
|
|
@ -379,6 +414,7 @@ David Thomas <davidthomas426@gmail.com>
|
||||||
David Titarenco <david.titarenco@gmail.com>
|
David Titarenco <david.titarenco@gmail.com>
|
||||||
David Volquartz Lebech <david@lebech.info>
|
David Volquartz Lebech <david@lebech.info>
|
||||||
Davies Liu <davies.liu@gmail.com>
|
Davies Liu <davies.liu@gmail.com>
|
||||||
|
Davor Kapsa <davor.kapsa@gmail.com>
|
||||||
Dean Prichard <dean.prichard@gmail.com>
|
Dean Prichard <dean.prichard@gmail.com>
|
||||||
Deepak Jois <deepak.jois@gmail.com>
|
Deepak Jois <deepak.jois@gmail.com>
|
||||||
Denis Bernard <db047h@gmail.com>
|
Denis Bernard <db047h@gmail.com>
|
||||||
|
|
@ -425,15 +461,19 @@ Dustin Sallings <dsallings@gmail.com>
|
||||||
Dustin Shields-Cloues <dcloues@gmail.com>
|
Dustin Shields-Cloues <dcloues@gmail.com>
|
||||||
Dvir Volk <dvir@everything.me> <dvirsky@gmail.com>
|
Dvir Volk <dvir@everything.me> <dvirsky@gmail.com>
|
||||||
Dylan Waits <dylan@waits.io>
|
Dylan Waits <dylan@waits.io>
|
||||||
|
Edan Bedrik <3d4nb3@gmail.com>
|
||||||
Eden Li <eden.li@gmail.com>
|
Eden Li <eden.li@gmail.com>
|
||||||
Edward Muller <edwardam@interlix.com>
|
Edward Muller <edwardam@interlix.com>
|
||||||
Egon Elbre <egonelbre@gmail.com>
|
Egon Elbre <egonelbre@gmail.com>
|
||||||
Ehren Kret <ehren.kret@gmail.com>
|
Ehren Kret <ehren.kret@gmail.com>
|
||||||
Eitan Adler <lists@eitanadler.com>
|
Eitan Adler <lists@eitanadler.com>
|
||||||
Eivind Uggedal <eivind@uggedal.com>
|
Eivind Uggedal <eivind@uggedal.com>
|
||||||
|
Elbert Fliek <efliek@gmail.com>
|
||||||
|
Elena Grahovac <elena@grahovac.me>
|
||||||
Elias Naur <elias.naur@gmail.com>
|
Elias Naur <elias.naur@gmail.com>
|
||||||
Elliot Morrison-Reed <elliotmr@gmail.com>
|
Elliot Morrison-Reed <elliotmr@gmail.com>
|
||||||
Emil Hessman <c.emil.hessman@gmail.com> <emil@hessman.se>
|
Emerson Lin <linyintor@gmail.com>
|
||||||
|
Emil Hessman <emil@hessman.se>
|
||||||
Emilien Kenler <hello@emilienkenler.com>
|
Emilien Kenler <hello@emilienkenler.com>
|
||||||
Emmanuel Odeke <emm.odeke@gmail.com> <odeke@ualberta.ca>
|
Emmanuel Odeke <emm.odeke@gmail.com> <odeke@ualberta.ca>
|
||||||
Eoghan Sherry <ejsherry@gmail.com>
|
Eoghan Sherry <ejsherry@gmail.com>
|
||||||
|
|
@ -444,6 +484,7 @@ Eric Garrido <ekg@google.com>
|
||||||
Eric Koleda <ekoleda+devrel@google.com>
|
Eric Koleda <ekoleda+devrel@google.com>
|
||||||
Eric Lagergren <ericscottlagergren@gmail.com>
|
Eric Lagergren <ericscottlagergren@gmail.com>
|
||||||
Eric Milliken <emilliken@gmail.com>
|
Eric Milliken <emilliken@gmail.com>
|
||||||
|
Eric Rescorla <ekr@rtfm.com>
|
||||||
Eric Roshan-Eisner <eric.d.eisner@gmail.com>
|
Eric Roshan-Eisner <eric.d.eisner@gmail.com>
|
||||||
Erik Aigner <aigner.erik@gmail.com>
|
Erik Aigner <aigner.erik@gmail.com>
|
||||||
Erik Dubbelboer <erik@dubbelboer.com>
|
Erik Dubbelboer <erik@dubbelboer.com>
|
||||||
|
|
@ -458,6 +499,7 @@ Euan Kemp <euank@euank.com>
|
||||||
Evan Broder <evan@stripe.com>
|
Evan Broder <evan@stripe.com>
|
||||||
Evan Brown <evanbrown@google.com>
|
Evan Brown <evanbrown@google.com>
|
||||||
Evan Hicks <evan.hicks2@gmail.com>
|
Evan Hicks <evan.hicks2@gmail.com>
|
||||||
|
Evan Jones <ej@evanjones.ca>
|
||||||
Evan Kroske <evankroske@google.com>
|
Evan Kroske <evankroske@google.com>
|
||||||
Evan Martin <evan.martin@gmail.com>
|
Evan Martin <evan.martin@gmail.com>
|
||||||
Evan Phoenix <evan@phx.io>
|
Evan Phoenix <evan@phx.io>
|
||||||
|
|
@ -481,7 +523,7 @@ Fedor Indutny <fedor@indutny.com>
|
||||||
Felipe Oliveira <felipeweb.programador@gmail.com>
|
Felipe Oliveira <felipeweb.programador@gmail.com>
|
||||||
Felix Geisendörfer <haimuiba@gmail.com>
|
Felix Geisendörfer <haimuiba@gmail.com>
|
||||||
Filip Gruszczyński <gruszczy@gmail.com>
|
Filip Gruszczyński <gruszczy@gmail.com>
|
||||||
Filippo Valsorda <filippo@cloudflare.com> <hi@filippo.io>
|
Filippo Valsorda <filippo@golang.org> <filippo@cloudflare.com> <hi@filippo.io>
|
||||||
Firmansyah Adiputra <frm.adiputra@gmail.com>
|
Firmansyah Adiputra <frm.adiputra@gmail.com>
|
||||||
Florian Uekermann <florian@uekermann-online.de> <f1@uekermann-online.de>
|
Florian Uekermann <florian@uekermann-online.de> <f1@uekermann-online.de>
|
||||||
Florian Weimer <fw@deneb.enyo.de>
|
Florian Weimer <fw@deneb.enyo.de>
|
||||||
|
|
@ -492,6 +534,8 @@ Francesc Campoy <campoy@golang.org>
|
||||||
Francisco Claude <fclaude@recoded.cl>
|
Francisco Claude <fclaude@recoded.cl>
|
||||||
Francisco Rojas <francisco.rojas.gallegos@gmail.com>
|
Francisco Rojas <francisco.rojas.gallegos@gmail.com>
|
||||||
Francisco Souza <franciscossouza@gmail.com>
|
Francisco Souza <franciscossouza@gmail.com>
|
||||||
|
Frank Somers <fsomers@arista.com>
|
||||||
|
Frederic Guillot <frederic.guillot@gmail.com>
|
||||||
Frederick Kelly Mayle III <frederickmayle@gmail.com>
|
Frederick Kelly Mayle III <frederickmayle@gmail.com>
|
||||||
Fredrik Enestad <fredrik.enestad@soundtrackyourbrand.com>
|
Fredrik Enestad <fredrik.enestad@soundtrackyourbrand.com>
|
||||||
Fredrik Forsmo <fredrik.forsmo@gmail.com>
|
Fredrik Forsmo <fredrik.forsmo@gmail.com>
|
||||||
|
|
@ -504,6 +548,7 @@ Gabriel Aszalos <gabriel.aszalos@gmail.com>
|
||||||
Gabriel Nicolas Avellaneda <avellaneda.gabriel@gmail.com>
|
Gabriel Nicolas Avellaneda <avellaneda.gabriel@gmail.com>
|
||||||
Gabriel Russell <gabriel.russell@gmail.com>
|
Gabriel Russell <gabriel.russell@gmail.com>
|
||||||
Gareth Paul Jones <gpj@foursquare.com>
|
Gareth Paul Jones <gpj@foursquare.com>
|
||||||
|
Garret Kelly <gdk@google.com>
|
||||||
Garrick Evans <garrick@google.com>
|
Garrick Evans <garrick@google.com>
|
||||||
Gary Burd <gary@beagledreams.com> <gary.burd@gmail.com>
|
Gary Burd <gary@beagledreams.com> <gary.burd@gmail.com>
|
||||||
Gary Elliott <garyelliott@google.com>
|
Gary Elliott <garyelliott@google.com>
|
||||||
|
|
@ -511,6 +556,7 @@ Gaurish Sharma <contact@gaurishsharma.com>
|
||||||
Gautham Thambidorai <gautham.dorai@gmail.com>
|
Gautham Thambidorai <gautham.dorai@gmail.com>
|
||||||
Geert-Johan Riemer <gjr19912@gmail.com>
|
Geert-Johan Riemer <gjr19912@gmail.com>
|
||||||
Gengliang Wang <ltnwgl@gmail.com>
|
Gengliang Wang <ltnwgl@gmail.com>
|
||||||
|
Geoff Berry <gberry.qdt@qualcommdatacenter.com>
|
||||||
Geoffroy Lorieux <lorieux.g@gmail.com>
|
Geoffroy Lorieux <lorieux.g@gmail.com>
|
||||||
Georg Reinke <guelfey@gmail.com>
|
Georg Reinke <guelfey@gmail.com>
|
||||||
George Gkirtsou <ggirtsou@gmail.com>
|
George Gkirtsou <ggirtsou@gmail.com>
|
||||||
|
|
@ -526,9 +572,12 @@ Glenn Lewis <gmlewis@google.com>
|
||||||
Gordon Klaus <gordon.klaus@gmail.com>
|
Gordon Klaus <gordon.klaus@gmail.com>
|
||||||
Graham King <graham4king@gmail.com>
|
Graham King <graham4king@gmail.com>
|
||||||
Graham Miller <graham.miller@gmail.com>
|
Graham Miller <graham.miller@gmail.com>
|
||||||
|
Grant Griffiths <ggp493@gmail.com>
|
||||||
Greg Poirier <greg.istehbest@gmail.com>
|
Greg Poirier <greg.istehbest@gmail.com>
|
||||||
Greg Ward <greg@gerg.ca>
|
Greg Ward <greg@gerg.ca>
|
||||||
Gregory Man <man.gregory@gmail.com>
|
Gregory Man <man.gregory@gmail.com>
|
||||||
|
Guilherme Garnier <guilherme.garnier@gmail.com>
|
||||||
|
Guilherme Rezende <guilhermebr@gmail.com>
|
||||||
Guillaume J. Charmes <guillaume@charmes.net>
|
Guillaume J. Charmes <guillaume@charmes.net>
|
||||||
Guobiao Mei <meiguobiao@gmail.com>
|
Guobiao Mei <meiguobiao@gmail.com>
|
||||||
Gustav Paul <gustav.paul@gmail.com>
|
Gustav Paul <gustav.paul@gmail.com>
|
||||||
|
|
@ -542,6 +591,7 @@ Hajime Hoshi <hajimehoshi@gmail.com>
|
||||||
Hallgrimur Gunnarsson <halg@google.com>
|
Hallgrimur Gunnarsson <halg@google.com>
|
||||||
Han-Wen Nienhuys <hanwen@google.com>
|
Han-Wen Nienhuys <hanwen@google.com>
|
||||||
Hang Qian <hangqian90@gmail.com>
|
Hang Qian <hangqian90@gmail.com>
|
||||||
|
Hanjun Kim <hallazzang@gmail.com>
|
||||||
Hari haran <hariharan.uno@gmail.com>
|
Hari haran <hariharan.uno@gmail.com>
|
||||||
Hariharan Srinath <srinathh@gmail.com>
|
Hariharan Srinath <srinathh@gmail.com>
|
||||||
Harley Laue <losinggeneration@gmail.com>
|
Harley Laue <losinggeneration@gmail.com>
|
||||||
|
|
@ -554,9 +604,14 @@ Hector Martin Cantero <hector@marcansoft.com>
|
||||||
Henning Schmiedehausen <henning@schmiedehausen.org>
|
Henning Schmiedehausen <henning@schmiedehausen.org>
|
||||||
Henrik Edwards <henrik.edwards@gmail.com>
|
Henrik Edwards <henrik.edwards@gmail.com>
|
||||||
Henrik Hodne <henrik@hodne.io>
|
Henrik Hodne <henrik@hodne.io>
|
||||||
|
Henry Adi Sumarto <henry.adisumarto@gmail.com>
|
||||||
|
Henry Bubert <google@mindeco.de>
|
||||||
Henry Chang <mr.changyuheng@gmail.com>
|
Henry Chang <mr.changyuheng@gmail.com>
|
||||||
Herbert Georg Fischer <herbert.fischer@gmail.com>
|
Herbert Georg Fischer <herbert.fischer@gmail.com>
|
||||||
|
Herbie Ong <herbie@google.com>
|
||||||
Heschi Kreinick <heschi@google.com>
|
Heschi Kreinick <heschi@google.com>
|
||||||
|
Hilko Bengen <bengen@hilluzination.de>
|
||||||
|
Hiroaki Nakamura <hnakamur@gmail.com>
|
||||||
Hironao OTSUBO <motemen@gmail.com>
|
Hironao OTSUBO <motemen@gmail.com>
|
||||||
Hiroshi Ioka <hirochachacha@gmail.com>
|
Hiroshi Ioka <hirochachacha@gmail.com>
|
||||||
Hitoshi Mitake <mitake.hitoshi@gmail.com>
|
Hitoshi Mitake <mitake.hitoshi@gmail.com>
|
||||||
|
|
@ -570,6 +625,7 @@ Hu Keping <hukeping@huawei.com>
|
||||||
Hugues Bruant <hugues.bruant@gmail.com>
|
Hugues Bruant <hugues.bruant@gmail.com>
|
||||||
Hyang-Ah Hana Kim <hakim@google.com> <hyangah@gmail.com>
|
Hyang-Ah Hana Kim <hakim@google.com> <hyangah@gmail.com>
|
||||||
Ian Gudger <ian@loosescre.ws>
|
Ian Gudger <ian@loosescre.ws>
|
||||||
|
Ian Kent <iankent85@gmail.com>
|
||||||
Ian Lance Taylor <iant@golang.org>
|
Ian Lance Taylor <iant@golang.org>
|
||||||
Ibrahim AshShohail <ibra.sho@gmail.com>
|
Ibrahim AshShohail <ibra.sho@gmail.com>
|
||||||
Icarus Sparry <golang@icarus.freeuk.com>
|
Icarus Sparry <golang@icarus.freeuk.com>
|
||||||
|
|
@ -577,13 +633,17 @@ Iccha Sethi <icchasethi@gmail.com>
|
||||||
Idora Shinatose <idora.shinatose@gmail.com>
|
Idora Shinatose <idora.shinatose@gmail.com>
|
||||||
Igor Bernstein <igorbernstein@google.com>
|
Igor Bernstein <igorbernstein@google.com>
|
||||||
Igor Dolzhikov <bluesriverz@gmail.com>
|
Igor Dolzhikov <bluesriverz@gmail.com>
|
||||||
|
Igor Vashyst <ivashyst@gmail.com>
|
||||||
Ilya Tocar <ilya.tocar@intel.com>
|
Ilya Tocar <ilya.tocar@intel.com>
|
||||||
INADA Naoki <songofacandy@gmail.com>
|
INADA Naoki <songofacandy@gmail.com>
|
||||||
|
Inanc Gumus <m@inanc.io>
|
||||||
Ingo Krabbe <ikrabbe.ask@gmail.com>
|
Ingo Krabbe <ikrabbe.ask@gmail.com>
|
||||||
Ingo Oeser <nightlyone@googlemail.com> <nightlyone@gmail.com>
|
Ingo Oeser <nightlyone@googlemail.com> <nightlyone@gmail.com>
|
||||||
Irieda Noboru <irieda@gmail.com>
|
Irieda Noboru <irieda@gmail.com>
|
||||||
Isaac Wagner <ibw@isaacwagner.me>
|
Isaac Wagner <ibw@isaacwagner.me>
|
||||||
|
Iskander Sharipov <iskander.sharipov@intel.com> <quasilyte@gmail.com>
|
||||||
Ivan Babrou <ivan@cloudflare.com>
|
Ivan Babrou <ivan@cloudflare.com>
|
||||||
|
Ivan Bertona <ivan.bertona@gmail.com>
|
||||||
Ivan Krasin <krasin@golang.org>
|
Ivan Krasin <krasin@golang.org>
|
||||||
Ivan Moscoso <moscoso@gmail.com>
|
Ivan Moscoso <moscoso@gmail.com>
|
||||||
Ivan Ukhov <ivan.ukhov@gmail.com>
|
Ivan Ukhov <ivan.ukhov@gmail.com>
|
||||||
|
|
@ -605,6 +665,7 @@ James David Chalfant <james.chalfant@gmail.com>
|
||||||
James Fysh <james.fysh@gmail.com>
|
James Fysh <james.fysh@gmail.com>
|
||||||
James Gray <james@james4k.com>
|
James Gray <james@james4k.com>
|
||||||
James Hartig <fastest963@gmail.com>
|
James Hartig <fastest963@gmail.com>
|
||||||
|
James Lawrence <jljatone@gmail.com>
|
||||||
James Meneghello <rawrz0r@gmail.com>
|
James Meneghello <rawrz0r@gmail.com>
|
||||||
James Myers <jfmyers9@gmail.com>
|
James Myers <jfmyers9@gmail.com>
|
||||||
James Neve <jamesoneve@gmail.com>
|
James Neve <jamesoneve@gmail.com>
|
||||||
|
|
@ -614,11 +675,13 @@ James Schofield <james@shoeboxapp.com>
|
||||||
James Smith <jrs1995@icloud.com>
|
James Smith <jrs1995@icloud.com>
|
||||||
James Sweet <james.sweet88@googlemail.com>
|
James Sweet <james.sweet88@googlemail.com>
|
||||||
James Toy <nil@opensesame.st>
|
James Toy <nil@opensesame.st>
|
||||||
|
James Treanor <jtreanor3@gmail.com>
|
||||||
James Tucker <raggi@google.com>
|
James Tucker <raggi@google.com>
|
||||||
James Whitehead <jnwhiteh@gmail.com>
|
James Whitehead <jnwhiteh@gmail.com>
|
||||||
Jamie Beverly <jamie.r.beverly@gmail.com>
|
Jamie Beverly <jamie.r.beverly@gmail.com>
|
||||||
Jamie Gennis <jgennis@google.com> <jgennis@gmail.com>
|
Jamie Gennis <jgennis@google.com> <jgennis@gmail.com>
|
||||||
Jamie Kerr <jkerr113@googlemail.com>
|
Jamie Kerr <jkerr113@googlemail.com>
|
||||||
|
Jamie Liu <jamieliu@google.com>
|
||||||
Jamie Stackhouse <contin673@gmail.com>
|
Jamie Stackhouse <contin673@gmail.com>
|
||||||
Jamie Turner <jamwt@dropbox.com>
|
Jamie Turner <jamwt@dropbox.com>
|
||||||
Jamie Wilkinson <jaq@spacepants.org>
|
Jamie Wilkinson <jaq@spacepants.org>
|
||||||
|
|
@ -630,6 +693,7 @@ Jan Mercl <0xjnml@gmail.com> <befelemepeseveze@gmail.com>
|
||||||
Jan Newmarch <jan.newmarch@gmail.com>
|
Jan Newmarch <jan.newmarch@gmail.com>
|
||||||
Jan Ziak <0xe2.0x9a.0x9b@gmail.com>
|
Jan Ziak <0xe2.0x9a.0x9b@gmail.com>
|
||||||
Jani Monoses <jani.monoses@ubuntu.com> <jani.monoses@gmail.com>
|
Jani Monoses <jani.monoses@ubuntu.com> <jani.monoses@gmail.com>
|
||||||
|
Jared Culp <jculp14@gmail.com>
|
||||||
Jaroslavas Počepko <jp@webmaster.ms>
|
Jaroslavas Počepko <jp@webmaster.ms>
|
||||||
Jason Barnett <jason.w.barnett@gmail.com>
|
Jason Barnett <jason.w.barnett@gmail.com>
|
||||||
Jason Buberel <jbuberel@google.com>
|
Jason Buberel <jbuberel@google.com>
|
||||||
|
|
@ -638,11 +702,15 @@ Jason Del Ponte <delpontej@gmail.com>
|
||||||
Jason Hall <jasonhall@google.com>
|
Jason Hall <jasonhall@google.com>
|
||||||
Jason Smale <jsmale@zendesk.com>
|
Jason Smale <jsmale@zendesk.com>
|
||||||
Jason Travis <infomaniac7@gmail.com>
|
Jason Travis <infomaniac7@gmail.com>
|
||||||
|
Jason Wangsadinata <jwangsadinata@gmail.com>
|
||||||
|
Javier Segura <javism@gmail.com>
|
||||||
Jay Conrod <jayconrod@google.com>
|
Jay Conrod <jayconrod@google.com>
|
||||||
Jay Weisskopf <jay@jayschwa.net>
|
Jay Weisskopf <jay@jayschwa.net>
|
||||||
|
Jean-Francois Cantin <jfcantin@gmail.com>
|
||||||
Jean-Marc Eurin <jmeurin@google.com>
|
Jean-Marc Eurin <jmeurin@google.com>
|
||||||
Jean-Nicolas Moal <jn.moal@gmail.com>
|
Jean-Nicolas Moal <jn.moal@gmail.com>
|
||||||
Jed Denlea <jed@fastly.com>
|
Jed Denlea <jed@fastly.com>
|
||||||
|
Jeet Parekh <jeetparekh96@gmail.com>
|
||||||
Jeff (Zhefu) Jiang <jeffjiang@google.com>
|
Jeff (Zhefu) Jiang <jeffjiang@google.com>
|
||||||
Jeff Craig <jeffcraig@google.com>
|
Jeff Craig <jeffcraig@google.com>
|
||||||
Jeff Hodges <jeff@somethingsimilar.com>
|
Jeff Hodges <jeff@somethingsimilar.com>
|
||||||
|
|
@ -651,6 +719,7 @@ Jeff R. Allen <jra@nella.org> <jeff.allen@gmail.com>
|
||||||
Jeff Sickel <jas@corpus-callosum.com>
|
Jeff Sickel <jas@corpus-callosum.com>
|
||||||
Jeff Wendling <jeff@spacemonkey.com>
|
Jeff Wendling <jeff@spacemonkey.com>
|
||||||
Jeffrey H <jeffreyh192@gmail.com>
|
Jeffrey H <jeffreyh192@gmail.com>
|
||||||
|
Jelte Fennema <github-tech@jeltef.nl>
|
||||||
Jens Frederich <jfrederich@gmail.com>
|
Jens Frederich <jfrederich@gmail.com>
|
||||||
Jeremiah Harmsen <jeremiah@google.com>
|
Jeremiah Harmsen <jeremiah@google.com>
|
||||||
Jeremy Jackins <jeremyjackins@gmail.com>
|
Jeremy Jackins <jeremyjackins@gmail.com>
|
||||||
|
|
@ -664,12 +733,14 @@ Jihyun Yu <yjh0502@gmail.com>
|
||||||
Jim Cote <jfcote87@gmail.com>
|
Jim Cote <jfcote87@gmail.com>
|
||||||
Jim Kingdon <jim@bolt.me>
|
Jim Kingdon <jim@bolt.me>
|
||||||
Jim McGrath <jimmc2@gmail.com>
|
Jim McGrath <jimmc2@gmail.com>
|
||||||
|
Jimmy Frasche <soapboxcicero@gmail.com>
|
||||||
Jimmy Zelinskie <jimmyzelinskie@gmail.com>
|
Jimmy Zelinskie <jimmyzelinskie@gmail.com>
|
||||||
Jin-wook Jeong <jeweljar@hanmail.net>
|
Jin-wook Jeong <jeweljar@hanmail.net>
|
||||||
Jingcheng Zhang <diogin@gmail.com>
|
Jingcheng Zhang <diogin@gmail.com>
|
||||||
Jingguo Yao <yaojingguo@gmail.com>
|
Jingguo Yao <yaojingguo@gmail.com>
|
||||||
Jiong Du <londevil@gmail.com>
|
Jiong Du <londevil@gmail.com>
|
||||||
Jirka Daněk <dnk@mail.muni.cz>
|
Jirka Daněk <dnk@mail.muni.cz>
|
||||||
|
Jiulong Wang <jiulongw@gmail.com>
|
||||||
Joakim Sernbrant <serbaut@gmail.com>
|
Joakim Sernbrant <serbaut@gmail.com>
|
||||||
Joe Farrell <joe2farrell@gmail.com>
|
Joe Farrell <joe2farrell@gmail.com>
|
||||||
Joe Harrison <joehazzers@gmail.com>
|
Joe Harrison <joehazzers@gmail.com>
|
||||||
|
|
@ -734,10 +805,13 @@ Josh Holland <jrh@joshh.co.uk>
|
||||||
Josh Roppo <joshroppo@gmail.com>
|
Josh Roppo <joshroppo@gmail.com>
|
||||||
Joshua Boelter <joshua.boelter@intel.com>
|
Joshua Boelter <joshua.boelter@intel.com>
|
||||||
Joshua Chase <jcjoshuachase@gmail.com>
|
Joshua Chase <jcjoshuachase@gmail.com>
|
||||||
|
Joshua Rubin <joshua@rubixconsulting.com>
|
||||||
Josselin Costanzi <josselin@costanzi.fr>
|
Josselin Costanzi <josselin@costanzi.fr>
|
||||||
Jostein Stuhaug <js@solidsystem.no>
|
Jostein Stuhaug <js@solidsystem.no>
|
||||||
JP Sugarbroad <jpsugar@google.com>
|
JP Sugarbroad <jpsugar@google.com>
|
||||||
JT Olds <jtolds@xnet5.com>
|
JT Olds <jtolds@xnet5.com>
|
||||||
|
Juan Carlos <juanjcsr@gmail.com>
|
||||||
|
Jude Pereira <judebpereira@gmail.com>
|
||||||
Jukka-Pekka Kekkonen <karatepekka@gmail.com>
|
Jukka-Pekka Kekkonen <karatepekka@gmail.com>
|
||||||
Julia Hansbrough <flowerhack@google.com>
|
Julia Hansbrough <flowerhack@google.com>
|
||||||
Julian Kornberger <jk+github@digineo.de>
|
Julian Kornberger <jk+github@digineo.de>
|
||||||
|
|
@ -746,6 +820,7 @@ Julian Phillips <julian@quantumfyre.co.uk>
|
||||||
Julien Schmidt <google@julienschmidt.com>
|
Julien Schmidt <google@julienschmidt.com>
|
||||||
Julio Montes <julio.montes@intel.com>
|
Julio Montes <julio.montes@intel.com>
|
||||||
Jungho Ahn <jhahn@google.com>
|
Jungho Ahn <jhahn@google.com>
|
||||||
|
Junya Hayashi <ledmonster@gmail.com>
|
||||||
Jure Ham <jure.ham@zemanta.com>
|
Jure Ham <jure.ham@zemanta.com>
|
||||||
Justin Nuß <nuss.justin@gmail.com>
|
Justin Nuß <nuss.justin@gmail.com>
|
||||||
Justyn Temme <justyntemme@gmail.com>
|
Justyn Temme <justyntemme@gmail.com>
|
||||||
|
|
@ -758,7 +833,9 @@ Kamil Chmielewski <kamil.chm@gmail.com>
|
||||||
Kamil Kisiel <kamil@kamilkisiel.net> <kamil.kisiel@gmail.com>
|
Kamil Kisiel <kamil@kamilkisiel.net> <kamil.kisiel@gmail.com>
|
||||||
Kang Hu <hukangustc@gmail.com>
|
Kang Hu <hukangustc@gmail.com>
|
||||||
Karan Dhiman <karandhi@ca.ibm.com>
|
Karan Dhiman <karandhi@ca.ibm.com>
|
||||||
|
Karel Pazdera <pazderak@gmail.com>
|
||||||
Karoly Negyesi <chx1975@gmail.com>
|
Karoly Negyesi <chx1975@gmail.com>
|
||||||
|
Karsten Köhler <karsten.koehler95@gmail.com>
|
||||||
Kashav Madan <kshvmdn@gmail.com>
|
Kashav Madan <kshvmdn@gmail.com>
|
||||||
Kate Manson <kate.manson@izettle.com>
|
Kate Manson <kate.manson@izettle.com>
|
||||||
Kato Kazuyoshi <kato.kazuyoshi@gmail.com>
|
Kato Kazuyoshi <kato.kazuyoshi@gmail.com>
|
||||||
|
|
@ -779,6 +856,7 @@ Ken Rockot <ken@oz.gs> <ken.rockot@gmail.com>
|
||||||
Ken Sedgwick <ken@bonsai.com>
|
Ken Sedgwick <ken@bonsai.com>
|
||||||
Ken Thompson <ken@golang.org>
|
Ken Thompson <ken@golang.org>
|
||||||
Kenji Kaneda <kenji.kaneda@gmail.com>
|
Kenji Kaneda <kenji.kaneda@gmail.com>
|
||||||
|
Kenji Yano <kenji.yano@gmail.com>
|
||||||
Kenneth Shaw <kenshaw@gmail.com>
|
Kenneth Shaw <kenshaw@gmail.com>
|
||||||
Kenny Grant <kennygrant@gmail.com>
|
Kenny Grant <kennygrant@gmail.com>
|
||||||
Kevin Ballard <kevin@sb.org>
|
Kevin Ballard <kevin@sb.org>
|
||||||
|
|
@ -786,10 +864,13 @@ Kevin Burke <kev@inburke.com>
|
||||||
Kevin Kirsche <kev.kirsche@gmail.com>
|
Kevin Kirsche <kev.kirsche@gmail.com>
|
||||||
Kevin Klues <klueska@gmail.com> <klueska@google.com>
|
Kevin Klues <klueska@gmail.com> <klueska@google.com>
|
||||||
Kevin Malachowski <chowski@google.com>
|
Kevin Malachowski <chowski@google.com>
|
||||||
|
Kevin Ruffin <kruffin@gmail.com>
|
||||||
Kevin Vu <kevin.m.vu@gmail.com>
|
Kevin Vu <kevin.m.vu@gmail.com>
|
||||||
|
Kieran Colford <kieran@kcolford.com>
|
||||||
Kim Shrier <kshrier@racktopsystems.com>
|
Kim Shrier <kshrier@racktopsystems.com>
|
||||||
Kim Yongbin <kybinz@gmail.com>
|
Kim Yongbin <kybinz@gmail.com>
|
||||||
Kirill Smelkov <kirr@nexedi.com>
|
Kirill Smelkov <kirr@nexedi.com>
|
||||||
|
Kirk Han <kirk91.han@gmail.com>
|
||||||
Kirklin McDonald <kirklin.mcdonald@gmail.com>
|
Kirklin McDonald <kirklin.mcdonald@gmail.com>
|
||||||
Klaus Post <klauspost@gmail.com>
|
Klaus Post <klauspost@gmail.com>
|
||||||
Kodie Goodwin <kodiegoodwin@gmail.com>
|
Kodie Goodwin <kodiegoodwin@gmail.com>
|
||||||
|
|
@ -801,31 +882,40 @@ Kris Nova <kris@nivenly.com>
|
||||||
Kris Rousey <krousey@google.com>
|
Kris Rousey <krousey@google.com>
|
||||||
Kristopher Watts <traetox@gmail.com>
|
Kristopher Watts <traetox@gmail.com>
|
||||||
Kun Li <likunarmstrong@gmail.com>
|
Kun Li <likunarmstrong@gmail.com>
|
||||||
|
Kunpei Sakai <namusyaka@gmail.com>
|
||||||
Kyle Consalus <consalus@gmail.com>
|
Kyle Consalus <consalus@gmail.com>
|
||||||
Kyle Isom <kyle@gokyle.net>
|
Kyle Isom <kyle@gokyle.net>
|
||||||
Kyle Jones <kyle@kyledj.com>
|
Kyle Jones <kyle@kyledj.com>
|
||||||
Kyle Lemons <kyle@kylelemons.net> <kevlar@google.com>
|
Kyle Lemons <kyle@kylelemons.net> <kevlar@google.com>
|
||||||
|
Kyle Shannon <kyle@pobox.com>
|
||||||
|
Kyohei Kadota <lufia@lufia.org>
|
||||||
Kyrylo Silin <silin@kyrylo.org>
|
Kyrylo Silin <silin@kyrylo.org>
|
||||||
L Campbell <unpantsu@gmail.com>
|
L Campbell <unpantsu@gmail.com>
|
||||||
Lai Jiangshan <eag0628@gmail.com>
|
Lai Jiangshan <eag0628@gmail.com>
|
||||||
|
Lakshay Garg <lakshay.garg.1996@gmail.com>
|
||||||
|
Lann Martin <lannm@google.com>
|
||||||
Larry Hosken <lahosken@golang.org>
|
Larry Hosken <lahosken@golang.org>
|
||||||
Lars Jeppesen <jeppesen.lars@gmail.com>
|
Lars Jeppesen <jeppesen.lars@gmail.com>
|
||||||
Lars Wiegman <lars@namsral.com>
|
Lars Wiegman <lars@namsral.com>
|
||||||
Larz Conwell <larzconwell@gmail.com>
|
Larz Conwell <larzconwell@gmail.com>
|
||||||
|
Laurent Voisin <lpvoisin@gmail.com>
|
||||||
Laurie Clark-Michalek <laurie@qubit.com>
|
Laurie Clark-Michalek <laurie@qubit.com>
|
||||||
LE Manh Cuong <cuong.manhle.vn@gmail.com>
|
LE Manh Cuong <cuong.manhle.vn@gmail.com>
|
||||||
Lee Hinman <hinman@gmail.com>
|
Lee Hinman <hinman@gmail.com>
|
||||||
Lee Packham <lpackham@gmail.com>
|
Lee Packham <lpackham@gmail.com>
|
||||||
|
Leigh McCulloch <leighmcc@gmail.com>
|
||||||
Leo Rudberg <ljr@google.com>
|
Leo Rudberg <ljr@google.com>
|
||||||
Leon Klingele <git@leonklingele.de>
|
Leon Klingele <git@leonklingele.de>
|
||||||
Lev Shamardin <shamardin@gmail.com>
|
Lev Shamardin <shamardin@gmail.com>
|
||||||
Lewin Bormann <lewin.bormann@gmail.com>
|
Lewin Bormann <lewin.bormann@gmail.com>
|
||||||
Lion Yang <lion@aosc.xyz>
|
Lion Yang <lion@aosc.xyz>
|
||||||
Lloyd Dewolf <foolswisdom@gmail.com>
|
Lloyd Dewolf <foolswisdom@gmail.com>
|
||||||
|
Lorenz Bauer <lmb@cloudflare.com>
|
||||||
Lorenzo Masini <rugginoso@develer.com>
|
Lorenzo Masini <rugginoso@develer.com>
|
||||||
Lorenzo Stoakes <lstoakes@gmail.com>
|
Lorenzo Stoakes <lstoakes@gmail.com>
|
||||||
Louis Kruger <louisk@google.com>
|
Louis Kruger <louisk@google.com>
|
||||||
Luan Santos <cfcluan@gmail.com>
|
Luan Santos <cfcluan@gmail.com>
|
||||||
|
Luca Bruno <luca.bruno@coreos.com>
|
||||||
Luca Greco <luca.greco@alcacoop.it>
|
Luca Greco <luca.greco@alcacoop.it>
|
||||||
Lucas Bremgartner <lucas.bremgartner@gmail.com>
|
Lucas Bremgartner <lucas.bremgartner@gmail.com>
|
||||||
Lucas Clemente <lclemente@google.com>
|
Lucas Clemente <lclemente@google.com>
|
||||||
|
|
@ -837,15 +927,20 @@ Luit van Drongelen <luitvd@gmail.com>
|
||||||
Luka Zakrajšek <tr00.g33k@gmail.com>
|
Luka Zakrajšek <tr00.g33k@gmail.com>
|
||||||
Lukasz Milewski <lmmilewski@gmail.com>
|
Lukasz Milewski <lmmilewski@gmail.com>
|
||||||
Luke Curley <qpingu@gmail.com>
|
Luke Curley <qpingu@gmail.com>
|
||||||
|
Luke Granger-Brown <git@lukegb.com>
|
||||||
Luna Duclos <luna.duclos@palmstonegames.com>
|
Luna Duclos <luna.duclos@palmstonegames.com>
|
||||||
Luuk van Dijk <lvd@golang.org> <lvd@google.com>
|
Luuk van Dijk <lvd@golang.org> <lvd@google.com>
|
||||||
|
Lyle Franklin <lylejfranklin@gmail.com>
|
||||||
Lynn Boger <laboger@linux.vnet.ibm.com>
|
Lynn Boger <laboger@linux.vnet.ibm.com>
|
||||||
Ma Peiqi <mapeiqi2017@gmail.com>
|
Ma Peiqi <mapeiqi2017@gmail.com>
|
||||||
Magnus Hiie <magnus.hiie@gmail.com>
|
Magnus Hiie <magnus.hiie@gmail.com>
|
||||||
|
Maicon Costa <maiconscosta@gmail.com>
|
||||||
Maksym Trykur <maksym.trykur@gmail.com>
|
Maksym Trykur <maksym.trykur@gmail.com>
|
||||||
Mal Curtis <mal@mal.co.nz>
|
Mal Curtis <mal@mal.co.nz>
|
||||||
Manfred Touron <m@42.am>
|
Manfred Touron <m@42.am>
|
||||||
|
Manish Goregaokar <manishsmail@gmail.com>
|
||||||
Manoj Dayaram <platform-dev@moovweb.com> <manoj.dayaram@moovweb.com>
|
Manoj Dayaram <platform-dev@moovweb.com> <manoj.dayaram@moovweb.com>
|
||||||
|
Mansour Rahimi <rahimi.mnr@gmail.com>
|
||||||
Manu Garg <manugarg@google.com>
|
Manu Garg <manugarg@google.com>
|
||||||
Manu S Ajith <neo@codingarena.in>
|
Manu S Ajith <neo@codingarena.in>
|
||||||
Manuel Mendez <mmendez534@gmail.com>
|
Manuel Mendez <mmendez534@gmail.com>
|
||||||
|
|
@ -861,9 +956,12 @@ Marius Nuennerich <mnu@google.com>
|
||||||
Mark Adams <mark@markadams.me>
|
Mark Adams <mark@markadams.me>
|
||||||
Mark Bucciarelli <mkbucc@gmail.com>
|
Mark Bucciarelli <mkbucc@gmail.com>
|
||||||
Mark Harrison <marhar@google.com>
|
Mark Harrison <marhar@google.com>
|
||||||
|
Mark Percival <m@mdp.im>
|
||||||
|
Mark Pulford <mark@kyne.com.au>
|
||||||
Mark Ryan <mark.d.ryan@intel.com>
|
Mark Ryan <mark.d.ryan@intel.com>
|
||||||
Mark Severson <miquella@gmail.com>
|
Mark Severson <miquella@gmail.com>
|
||||||
Mark Theunissen <mark.theunissen@gmail.com>
|
Mark Theunissen <mark.theunissen@gmail.com>
|
||||||
|
Mark Wolfe <mark@wolfe.id.au>
|
||||||
Mark Zavislak <zavislak@google.com>
|
Mark Zavislak <zavislak@google.com>
|
||||||
Marko Juhani Silokunnas <marko.silokunnas@gmail.com>
|
Marko Juhani Silokunnas <marko.silokunnas@gmail.com>
|
||||||
Marko Mikulicic <mkm@google.com>
|
Marko Mikulicic <mkm@google.com>
|
||||||
|
|
@ -884,6 +982,7 @@ Martin Neubauer <m.ne@gmx.net>
|
||||||
Martin Olsen <github.com@martinolsen.net>
|
Martin Olsen <github.com@martinolsen.net>
|
||||||
Martin Olsson <martin@minimum.se>
|
Martin Olsson <martin@minimum.se>
|
||||||
Martin Probst <martin@probst.io>
|
Martin Probst <martin@probst.io>
|
||||||
|
Martins Sipenko <martins.sipenko@gmail.com>
|
||||||
Martynas Budriūnas <mabu@google.com>
|
Martynas Budriūnas <mabu@google.com>
|
||||||
Marvin Stenger <marvin.stenger94@gmail.com>
|
Marvin Stenger <marvin.stenger94@gmail.com>
|
||||||
Marwan Sulaiman <marwan.sulaiman@work.co>
|
Marwan Sulaiman <marwan.sulaiman@work.co>
|
||||||
|
|
@ -891,7 +990,10 @@ Maryan Hratson <gmarik@gmail.com>
|
||||||
Masahiro Furudate <masahiro.furudate@gmail.com>
|
Masahiro Furudate <masahiro.furudate@gmail.com>
|
||||||
Masahiro Wakame <vvakame@gmail.com>
|
Masahiro Wakame <vvakame@gmail.com>
|
||||||
Masaki Yoshida <yoshida.masaki@gmail.com>
|
Masaki Yoshida <yoshida.masaki@gmail.com>
|
||||||
|
Mat Byczkowski <mbyczkowski@gmail.com>
|
||||||
Máté Gulyás <mgulyas86@gmail.com>
|
Máté Gulyás <mgulyas86@gmail.com>
|
||||||
|
Matej Baćo <matejbaco@gmail.com>
|
||||||
|
Mateus Amin <mateus.amin@gmail.com>
|
||||||
Mateusz Czapliński <czapkofan@gmail.com>
|
Mateusz Czapliński <czapkofan@gmail.com>
|
||||||
Mathias Beke <git@denbeke.be>
|
Mathias Beke <git@denbeke.be>
|
||||||
Mathias Hall-Andersen <mathias@hall-andersen.dk>
|
Mathias Hall-Andersen <mathias@hall-andersen.dk>
|
||||||
|
|
@ -902,6 +1004,7 @@ Matt Aimonetti <mattaimonetti@gmail.com>
|
||||||
Matt Blair <me@matthewblair.net>
|
Matt Blair <me@matthewblair.net>
|
||||||
Matt Bostock <matt@mattbostock.com>
|
Matt Bostock <matt@mattbostock.com>
|
||||||
Matt Brown <mdbrown@google.com>
|
Matt Brown <mdbrown@google.com>
|
||||||
|
Matt Dee <mdee@hioscar.com>
|
||||||
Matt Drollette <matt@drollette.com>
|
Matt Drollette <matt@drollette.com>
|
||||||
Matt Harden <matt.harden@gmail.com>
|
Matt Harden <matt.harden@gmail.com>
|
||||||
Matt Jibson <matt.jibson@gmail.com>
|
Matt Jibson <matt.jibson@gmail.com>
|
||||||
|
|
@ -914,6 +1017,7 @@ Matt Strong <mstrong1341@gmail.com>
|
||||||
Matt T. Proud <matt.proud@gmail.com>
|
Matt T. Proud <matt.proud@gmail.com>
|
||||||
Matt Williams <gh@mattyw.net> <mattyjwilliams@gmail.com>
|
Matt Williams <gh@mattyw.net> <mattyjwilliams@gmail.com>
|
||||||
Matthew Brennan <matty.brennan@gmail.com>
|
Matthew Brennan <matty.brennan@gmail.com>
|
||||||
|
Matthew Broberg <matthewbbroberg@gmail.com>
|
||||||
Matthew Cottingham <mattcottingham@gmail.com>
|
Matthew Cottingham <mattcottingham@gmail.com>
|
||||||
Matthew Dempsky <mdempsky@google.com>
|
Matthew Dempsky <mdempsky@google.com>
|
||||||
Matthew Denton <mdenton@skyportsystems.com>
|
Matthew Denton <mdenton@skyportsystems.com>
|
||||||
|
|
@ -921,17 +1025,21 @@ Matthew Holt <Matthew.Holt+git@gmail.com>
|
||||||
Matthew Horsnell <matthew.horsnell@gmail.com>
|
Matthew Horsnell <matthew.horsnell@gmail.com>
|
||||||
Matthieu Hauglustaine <matt.hauglustaine@gmail.com>
|
Matthieu Hauglustaine <matt.hauglustaine@gmail.com>
|
||||||
Matthieu Olivier <olivier.matthieu@gmail.com>
|
Matthieu Olivier <olivier.matthieu@gmail.com>
|
||||||
|
Matthijs Kooijman <matthijs@stdin.nl>
|
||||||
Max Riveiro <kavu13@gmail.com>
|
Max Riveiro <kavu13@gmail.com>
|
||||||
|
Max Schmitt <max@schmitt.mx>
|
||||||
Maxim Khitrov <max@mxcrypt.com>
|
Maxim Khitrov <max@mxcrypt.com>
|
||||||
Maxim Pimenov <mpimenov@google.com>
|
Maxim Pimenov <mpimenov@google.com>
|
||||||
Maxim Ushakov <ushakov@google.com>
|
Maxim Ushakov <ushakov@google.com>
|
||||||
Maxime de Roucy <maxime.deroucy@gmail.com>
|
Maxime de Roucy <maxime.deroucy@gmail.com>
|
||||||
Máximo Cuadros Ortiz <mcuadros@gmail.com>
|
Máximo Cuadros Ortiz <mcuadros@gmail.com>
|
||||||
Maxwell Krohn <themax@gmail.com>
|
Maxwell Krohn <themax@gmail.com>
|
||||||
|
Mayank Kumar <krmayankk@gmail.com>
|
||||||
Meir Fischer <meirfischer@gmail.com>
|
Meir Fischer <meirfischer@gmail.com>
|
||||||
Meng Zhuo <mengzhuo1203@gmail.com>
|
Meng Zhuo <mengzhuo1203@gmail.com>
|
||||||
Mhd Sulhan <m.shulhan@gmail.com>
|
Mhd Sulhan <m.shulhan@gmail.com>
|
||||||
Micah Stetson <micah.stetson@gmail.com>
|
Micah Stetson <micah.stetson@gmail.com>
|
||||||
|
Michael Brandenburg <mbrandenburg@bolste.com>
|
||||||
Michael Chaten <mchaten@gmail.com>
|
Michael Chaten <mchaten@gmail.com>
|
||||||
Michael Darakananda <pongad@google.com>
|
Michael Darakananda <pongad@google.com>
|
||||||
Michael Edwards <medwards@walledcity.ca>
|
Michael Edwards <medwards@walledcity.ca>
|
||||||
|
|
@ -949,25 +1057,30 @@ Michael Marineau <michael.marineau@coreos.com>
|
||||||
Michael Matloob <matloob@google.com>
|
Michael Matloob <matloob@google.com>
|
||||||
Michael McConville <momcconville@gmail.com>
|
Michael McConville <momcconville@gmail.com>
|
||||||
Michael McGreevy <mcgreevy@golang.org>
|
Michael McGreevy <mcgreevy@golang.org>
|
||||||
|
Michael McLoughlin <mmcloughlin@gmail.com>
|
||||||
Michael Munday <munday@ca.ibm.com>
|
Michael Munday <munday@ca.ibm.com>
|
||||||
Michael Pearson <mipearson@gmail.com>
|
Michael Pearson <mipearson@gmail.com>
|
||||||
Michael Piatek <piatek@google.com>
|
Michael Piatek <piatek@google.com>
|
||||||
Michael Pratt <mpratt@google.com>
|
Michael Pratt <mpratt@google.com>
|
||||||
Michael Schaller <michael@5challer.de>
|
Michael Schaller <michael@5challer.de>
|
||||||
|
Michael Schurter <michael.schurter@gmail.com>
|
||||||
Michael Shields <mshields@google.com>
|
Michael Shields <mshields@google.com>
|
||||||
Michael Stapelberg <michael@stapelberg.de> <mstplbrg@googlemail.com>
|
Michael Stapelberg <michael@stapelberg.de> <mstplbrg@googlemail.com>
|
||||||
|
Michael Steinert <mike.steinert@gmail.com>
|
||||||
Michael T. Jones <mtj@google.com> <michael.jones@gmail.com>
|
Michael T. Jones <mtj@google.com> <michael.jones@gmail.com>
|
||||||
Michael Teichgräber <mteichgraeber@gmx.de> <mt4swm@googlemail.com>
|
Michael Teichgräber <mteichgraeber@gmx.de> <mt4swm@googlemail.com>
|
||||||
Michael Vetter <g.bluehut@gmail.com>
|
Michael Vetter <g.bluehut@gmail.com>
|
||||||
Michal Bohuslávek <mbohuslavek@gmail.com>
|
Michal Bohuslávek <mbohuslavek@gmail.com>
|
||||||
Michal Cierniak <cierniak@google.com>
|
Michal Cierniak <cierniak@google.com>
|
||||||
Michał Derkacz <ziutek@lnet.pl>
|
Michał Derkacz <ziutek@lnet.pl>
|
||||||
|
Michal Pristas <michal.pristas@gmail.com>
|
||||||
Michalis Kargakis <michaliskargakis@gmail.com>
|
Michalis Kargakis <michaliskargakis@gmail.com>
|
||||||
Michel Lespinasse <walken@google.com>
|
Michel Lespinasse <walken@google.com>
|
||||||
Miek Gieben <miek@miek.nl> <remigius.gieben@gmail.com>
|
Miek Gieben <miek@miek.nl> <remigius.gieben@gmail.com>
|
||||||
Miguel Mendez <stxmendez@gmail.com>
|
Miguel Mendez <stxmendez@gmail.com>
|
||||||
Miguel Molina <hi@mvader.me>
|
Miguel Molina <hi@mvader.me>
|
||||||
Mihai Borobocea <MihaiBorobocea@gmail.com>
|
Mihai Borobocea <MihaiBorobocea@gmail.com>
|
||||||
|
Mihail Minaev <minaev.mike@gmail.com>
|
||||||
Mikael Tillenius <mikti42@gmail.com>
|
Mikael Tillenius <mikti42@gmail.com>
|
||||||
Mike Andrews <mra@xoba.com>
|
Mike Andrews <mra@xoba.com>
|
||||||
Mike Appleby <mike@app.leby.org>
|
Mike Appleby <mike@app.leby.org>
|
||||||
|
|
@ -995,9 +1108,11 @@ Morten Siebuhr <sbhr@sbhr.dk>
|
||||||
Môshe van der Sterre <moshevds@gmail.com>
|
Môshe van der Sterre <moshevds@gmail.com>
|
||||||
Mostyn Bramley-Moore <mostyn@antipode.se>
|
Mostyn Bramley-Moore <mostyn@antipode.se>
|
||||||
Mrunal Patel <mrunalp@gmail.com>
|
Mrunal Patel <mrunalp@gmail.com>
|
||||||
|
Muhammad Falak R Wani <falakreyaz@gmail.com>
|
||||||
Muhammed Uluyol <uluyol0@gmail.com>
|
Muhammed Uluyol <uluyol0@gmail.com>
|
||||||
Mura Li <mura_li@castech.com.tw>
|
Mura Li <mura_li@castech.com.tw>
|
||||||
Nan Deng <monnand@gmail.com>
|
Nan Deng <monnand@gmail.com>
|
||||||
|
Naoki Kanatani <k12naoki@gmail.com>
|
||||||
Nathan Caza <mastercactapus@gmail.com>
|
Nathan Caza <mastercactapus@gmail.com>
|
||||||
Nathan Humphreys <nkhumphreys@gmail.com>
|
Nathan Humphreys <nkhumphreys@gmail.com>
|
||||||
Nathan John Youngman <nj@nathany.com>
|
Nathan John Youngman <nj@nathany.com>
|
||||||
|
|
@ -1027,6 +1142,7 @@ Nick Miyake <nmiyake@users.noreply.github.com>
|
||||||
Nick Patavalis <nick.patavalis@gmail.com>
|
Nick Patavalis <nick.patavalis@gmail.com>
|
||||||
Nick Petroni <npetroni@cs.umd.edu>
|
Nick Petroni <npetroni@cs.umd.edu>
|
||||||
Nick Robinson <nrobinson13@gmail.com>
|
Nick Robinson <nrobinson13@gmail.com>
|
||||||
|
Nicolas BRULEZ <n.brulez@gmail.com>
|
||||||
Nicolas Kaiser <nikai@nikai.net>
|
Nicolas Kaiser <nikai@nikai.net>
|
||||||
Nicolas Owens <mischief@offblast.org>
|
Nicolas Owens <mischief@offblast.org>
|
||||||
Nicolas S. Dade <nic.dade@gmail.com>
|
Nicolas S. Dade <nic.dade@gmail.com>
|
||||||
|
|
@ -1037,8 +1153,10 @@ Nik Nyby <nnyby@columbia.edu>
|
||||||
Niklas Schnelle <niklas.schnelle@gmail.com>
|
Niklas Schnelle <niklas.schnelle@gmail.com>
|
||||||
Niko Dziemba <niko@dziemba.com>
|
Niko Dziemba <niko@dziemba.com>
|
||||||
Nikolay Turpitko <nikolay@turpitko.com>
|
Nikolay Turpitko <nikolay@turpitko.com>
|
||||||
|
Nils Larsgård <nilsmagnus@gmail.com>
|
||||||
Niranjan Godbole <niranjan8192@gmail.com>
|
Niranjan Godbole <niranjan8192@gmail.com>
|
||||||
Noah Campbell <noahcampbell@gmail.com>
|
Noah Campbell <noahcampbell@gmail.com>
|
||||||
|
Noble Johnson <noblepoly@gmail.com>
|
||||||
Nodir Turakulov <nodir@google.com>
|
Nodir Turakulov <nodir@google.com>
|
||||||
Norberto Lopes <nlopes.ml@gmail.com>
|
Norberto Lopes <nlopes.ml@gmail.com>
|
||||||
Odin Ugedal <odin@ugedal.com>
|
Odin Ugedal <odin@ugedal.com>
|
||||||
|
|
@ -1073,6 +1191,7 @@ Patrick Riley <pfr@google.com>
|
||||||
Patrick Smith <pat42smith@gmail.com>
|
Patrick Smith <pat42smith@gmail.com>
|
||||||
Paul A Querna <paul.querna@gmail.com>
|
Paul A Querna <paul.querna@gmail.com>
|
||||||
Paul Borman <borman@google.com>
|
Paul Borman <borman@google.com>
|
||||||
|
Paul Boyd <boyd.paul2@gmail.com>
|
||||||
Paul Chang <paulchang@google.com>
|
Paul Chang <paulchang@google.com>
|
||||||
Paul Hammond <paul@paulhammond.org>
|
Paul Hammond <paul@paulhammond.org>
|
||||||
Paul Hankin <paulhankin@google.com>
|
Paul Hankin <paulhankin@google.com>
|
||||||
|
|
@ -1081,8 +1200,10 @@ Paul Lalonde <paul.a.lalonde@gmail.com>
|
||||||
Paul Marks <pmarks@google.com>
|
Paul Marks <pmarks@google.com>
|
||||||
Paul Meyer <paul.meyer@microsoft.com>
|
Paul Meyer <paul.meyer@microsoft.com>
|
||||||
Paul Nasrat <pnasrat@google.com>
|
Paul Nasrat <pnasrat@google.com>
|
||||||
|
Paul PISCUC <paul.piscuc@gmail.com>
|
||||||
Paul Querna <pquerna@apache.org>
|
Paul Querna <pquerna@apache.org>
|
||||||
Paul Rosania <paul.rosania@gmail.com>
|
Paul Rosania <paul.rosania@gmail.com>
|
||||||
|
Paul Ruest <pruest@gmail.com>
|
||||||
Paul Sbarra <Sbarra.Paul@gmail.com>
|
Paul Sbarra <Sbarra.Paul@gmail.com>
|
||||||
Paul Smith <paulsmith@pobox.com> <paulsmith@gmail.com>
|
Paul Smith <paulsmith@pobox.com> <paulsmith@gmail.com>
|
||||||
Paul van Brouwershaven <paul@vanbrouwershaven.com>
|
Paul van Brouwershaven <paul@vanbrouwershaven.com>
|
||||||
|
|
@ -1116,6 +1237,8 @@ Peter Waldschmidt <peter@waldschmidt.com>
|
||||||
Peter Waller <peter.waller@gmail.com>
|
Peter Waller <peter.waller@gmail.com>
|
||||||
Peter Weinberger <pjw@golang.org>
|
Peter Weinberger <pjw@golang.org>
|
||||||
Peter Williams <pwil3058@gmail.com>
|
Peter Williams <pwil3058@gmail.com>
|
||||||
|
Peter Wu <pwu@cloudflare.com>
|
||||||
|
Petrica Voicu <pvoicu@paypal.com>
|
||||||
Phil Pennock <pdp@golang.org>
|
Phil Pennock <pdp@golang.org>
|
||||||
Philip Børgesen <philip.borgesen@gmail.com>
|
Philip Børgesen <philip.borgesen@gmail.com>
|
||||||
Philip Hofer <phofer@umich.edu>
|
Philip Hofer <phofer@umich.edu>
|
||||||
|
|
@ -1125,6 +1248,7 @@ Pierre Roullon <pierre.roullon@gmail.com>
|
||||||
Piers <google@hellopiers.pro>
|
Piers <google@hellopiers.pro>
|
||||||
Pieter Droogendijk <pieter@binky.org.uk>
|
Pieter Droogendijk <pieter@binky.org.uk>
|
||||||
Pietro Gagliardi <pietro10@mac.com>
|
Pietro Gagliardi <pietro10@mac.com>
|
||||||
|
Pontus Leitzler <leitzler@gmail.com>
|
||||||
Prasanna Swaminathan <prasanna@mediamath.com>
|
Prasanna Swaminathan <prasanna@mediamath.com>
|
||||||
Prashant Varanasi <prashant@prashantv.com>
|
Prashant Varanasi <prashant@prashantv.com>
|
||||||
Pravendra Singh <hackpravj@gmail.com>
|
Pravendra Singh <hackpravj@gmail.com>
|
||||||
|
|
@ -1137,19 +1261,25 @@ Quentin Renard <contact@asticode.com>
|
||||||
Quentin Smith <quentin@golang.org>
|
Quentin Smith <quentin@golang.org>
|
||||||
Quinn Slack <sqs@sourcegraph.com>
|
Quinn Slack <sqs@sourcegraph.com>
|
||||||
Quoc-Viet Nguyen <afelion@gmail.com>
|
Quoc-Viet Nguyen <afelion@gmail.com>
|
||||||
|
Radek Sohlich <sohlich@gmail.com>
|
||||||
Radu Berinde <radu@cockroachlabs.com>
|
Radu Berinde <radu@cockroachlabs.com>
|
||||||
Rafal Jeczalik <rjeczalik@gmail.com>
|
Rafal Jeczalik <rjeczalik@gmail.com>
|
||||||
Rahul Chaudhry <rahulchaudhry@chromium.org>
|
Rahul Chaudhry <rahulchaudhry@chromium.org>
|
||||||
Raif S. Naffah <go@naffah-raif.name>
|
Raif S. Naffah <go@naffah-raif.name>
|
||||||
Rajat Goel <rajat.goel2010@gmail.com>
|
Rajat Goel <rajat.goel2010@gmail.com>
|
||||||
|
Rajath Agasthya <rajathagasthya@gmail.com>
|
||||||
|
Rajender Reddy Kompally <rajenderreddykompally@gmail.com>
|
||||||
Ralph Corderoy <ralph@inputplus.co.uk>
|
Ralph Corderoy <ralph@inputplus.co.uk>
|
||||||
|
Ramazan AYYILDIZ <rayyildiz@gmail.com>
|
||||||
Ramesh Dharan <dharan@google.com>
|
Ramesh Dharan <dharan@google.com>
|
||||||
Raph Levien <raph@google.com>
|
Raph Levien <raph@google.com>
|
||||||
Raphael Geronimi <raphael.geronimi@gmail.com>
|
Raphael Geronimi <raphael.geronimi@gmail.com>
|
||||||
Raul Silvera <rsilvera@google.com>
|
Raul Silvera <rsilvera@google.com>
|
||||||
|
RaviTeja Pothana <ravi.tezu@gmail.com>
|
||||||
Ray Tung <rtung@thoughtworks.com>
|
Ray Tung <rtung@thoughtworks.com>
|
||||||
Raymond Kazlauskas <raima220@gmail.com>
|
Raymond Kazlauskas <raima220@gmail.com>
|
||||||
Rebecca Stambler <rstambler@golang.org>
|
Rebecca Stambler <rstambler@golang.org>
|
||||||
|
Reilly Watson <reillywatson@gmail.com>
|
||||||
Reinaldo de Souza Jr <juniorz@gmail.com>
|
Reinaldo de Souza Jr <juniorz@gmail.com>
|
||||||
Remi Gillig <remigillig@gmail.com>
|
Remi Gillig <remigillig@gmail.com>
|
||||||
Rémy Oudompheng <oudomphe@phare.normalesup.org> <remyoudompheng@gmail.com>
|
Rémy Oudompheng <oudomphe@phare.normalesup.org> <remyoudompheng@gmail.com>
|
||||||
|
|
@ -1187,10 +1317,13 @@ Rodrigo Rafael Monti Kochenburger <divoxx@gmail.com>
|
||||||
Roger Pau Monné <royger@gmail.com>
|
Roger Pau Monné <royger@gmail.com>
|
||||||
Roger Peppe <rogpeppe@gmail.com>
|
Roger Peppe <rogpeppe@gmail.com>
|
||||||
Roland Shoemaker <rolandshoemaker@gmail.com>
|
Roland Shoemaker <rolandshoemaker@gmail.com>
|
||||||
|
Roman Budnikov <romanyx90@yandex.ru>
|
||||||
Ron Hashimoto <mail@h2so5.net>
|
Ron Hashimoto <mail@h2so5.net>
|
||||||
Ron Minnich <rminnich@gmail.com>
|
Ron Minnich <rminnich@gmail.com>
|
||||||
|
Ross Chater <rdchater@gmail.com>
|
||||||
Ross Light <light@google.com> <rlight2@gmail.com>
|
Ross Light <light@google.com> <rlight2@gmail.com>
|
||||||
Rowan Worth <sqweek@gmail.com>
|
Rowan Worth <sqweek@gmail.com>
|
||||||
|
Rudi Kramer <rudi.kramer@gmail.com>
|
||||||
Rui Ueyama <ruiu@google.com>
|
Rui Ueyama <ruiu@google.com>
|
||||||
Russ Cox <rsc@golang.org>
|
Russ Cox <rsc@golang.org>
|
||||||
Russell Haering <russellhaering@gmail.com>
|
Russell Haering <russellhaering@gmail.com>
|
||||||
|
|
@ -1202,6 +1335,8 @@ Ryan Hitchman <hitchmanr@gmail.com>
|
||||||
Ryan Lower <rpjlower@gmail.com>
|
Ryan Lower <rpjlower@gmail.com>
|
||||||
Ryan Seys <ryan@ryanseys.com>
|
Ryan Seys <ryan@ryanseys.com>
|
||||||
Ryan Slade <ryanslade@gmail.com>
|
Ryan Slade <ryanslade@gmail.com>
|
||||||
|
Ryoichi KATO <ryo1kato@gmail.com>
|
||||||
|
Ryuji Iwata <qt.luigi@gmail.com>
|
||||||
Ryuzo Yamamoto <ryuzo.yamamoto@gmail.com>
|
Ryuzo Yamamoto <ryuzo.yamamoto@gmail.com>
|
||||||
S.Çağlar Onur <caglar@10ur.org>
|
S.Çağlar Onur <caglar@10ur.org>
|
||||||
Sai Cheemalapati <saicheems@google.com>
|
Sai Cheemalapati <saicheems@google.com>
|
||||||
|
|
@ -1223,6 +1358,7 @@ Sasha Lionheart <lionhearts@google.com>
|
||||||
Sasha Sobol <sasha@scaledinference.com>
|
Sasha Sobol <sasha@scaledinference.com>
|
||||||
Scott Barron <scott.barron@github.com>
|
Scott Barron <scott.barron@github.com>
|
||||||
Scott Bell <scott@sctsm.com>
|
Scott Bell <scott@sctsm.com>
|
||||||
|
Scott Crunkleton <crunk1@gmail.com>
|
||||||
Scott Ferguson <scottwferg@gmail.com>
|
Scott Ferguson <scottwferg@gmail.com>
|
||||||
Scott Lawrence <bytbox@gmail.com>
|
Scott Lawrence <bytbox@gmail.com>
|
||||||
Scott Mansfield <smansfield@netflix.com>
|
Scott Mansfield <smansfield@netflix.com>
|
||||||
|
|
@ -1236,11 +1372,15 @@ Sean Harger <sharger@google.com>
|
||||||
Sean Rees <sean@erifax.org>
|
Sean Rees <sean@erifax.org>
|
||||||
Sebastien Binet <seb.binet@gmail.com>
|
Sebastien Binet <seb.binet@gmail.com>
|
||||||
Sébastien Paolacci <sebastien.paolacci@gmail.com>
|
Sébastien Paolacci <sebastien.paolacci@gmail.com>
|
||||||
|
Seiji Takahashi <timaki.st@gmail.com>
|
||||||
Sergei Skorobogatov <skorobo@rambler.ru>
|
Sergei Skorobogatov <skorobo@rambler.ru>
|
||||||
Sergey 'SnakE' Gromov <snake.scaly@gmail.com>
|
Sergey 'SnakE' Gromov <snake.scaly@gmail.com>
|
||||||
Sergey Arseev <sergey.arseev@intel.com>
|
Sergey Arseev <sergey.arseev@intel.com>
|
||||||
|
Sergey Frolov <sfrolov@google.com>
|
||||||
Sergey Mishin <sergeymishine@gmail.com>
|
Sergey Mishin <sergeymishine@gmail.com>
|
||||||
|
Sergey Semin <gray12511@gmail.com>
|
||||||
Sergio Luis O. B. Correia <sergio@correia.cc>
|
Sergio Luis O. B. Correia <sergio@correia.cc>
|
||||||
|
Sergiusz Bazanski <bazanski@gmail.com>
|
||||||
Seth Hoenig <seth.a.hoenig@gmail.com>
|
Seth Hoenig <seth.a.hoenig@gmail.com>
|
||||||
Seth Vargo <sethvargo@gmail.com>
|
Seth Vargo <sethvargo@gmail.com>
|
||||||
Shahar Kohanim <skohanim@gmail.com>
|
Shahar Kohanim <skohanim@gmail.com>
|
||||||
|
|
@ -1270,6 +1410,7 @@ Srdjan Petrovic <spetrovic@google.com>
|
||||||
Sridhar Venkatakrishnan <sridhar@laddoo.net>
|
Sridhar Venkatakrishnan <sridhar@laddoo.net>
|
||||||
StalkR <stalkr@stalkr.net>
|
StalkR <stalkr@stalkr.net>
|
||||||
Stan Schwertly <stan@schwertly.com>
|
Stan Schwertly <stan@schwertly.com>
|
||||||
|
Stanislav Afanasev <php.progger@gmail.com>
|
||||||
Stefan Nilsson <snilsson@nada.kth.se> <trolleriprofessorn@gmail.com>
|
Stefan Nilsson <snilsson@nada.kth.se> <trolleriprofessorn@gmail.com>
|
||||||
Stéphane Travostino <stephane.travostino@gmail.com>
|
Stéphane Travostino <stephane.travostino@gmail.com>
|
||||||
Stephen Ma <stephenm@golang.org>
|
Stephen Ma <stephenm@golang.org>
|
||||||
|
|
@ -1277,6 +1418,7 @@ Stephen McQuay <stephen@mcquay.me>
|
||||||
Stephen Searles <stephens2424@gmail.com>
|
Stephen Searles <stephens2424@gmail.com>
|
||||||
Stephen Weinberg <stephen@q5comm.com>
|
Stephen Weinberg <stephen@q5comm.com>
|
||||||
Steve Francia <spf@golang.org>
|
Steve Francia <spf@golang.org>
|
||||||
|
Steve Gilbert <stevegilbert23@gmail.com>
|
||||||
Steve McCoy <mccoyst@gmail.com>
|
Steve McCoy <mccoyst@gmail.com>
|
||||||
Steve Newman <snewman@google.com>
|
Steve Newman <snewman@google.com>
|
||||||
Steve Phillips <elimisteve@gmail.com>
|
Steve Phillips <elimisteve@gmail.com>
|
||||||
|
|
@ -1288,13 +1430,16 @@ Steven Hartland <steven.hartland@multiplay.co.uk>
|
||||||
Steven Wilkin <stevenwilkin@gmail.com>
|
Steven Wilkin <stevenwilkin@gmail.com>
|
||||||
Sugu Sougoumarane <ssougou@gmail.com>
|
Sugu Sougoumarane <ssougou@gmail.com>
|
||||||
Suharsh Sivakumar <suharshs@google.com>
|
Suharsh Sivakumar <suharshs@google.com>
|
||||||
|
Sukrit Handa <sukrit.handa@utoronto.ca>
|
||||||
Sunny <me@darkowlzz.space>
|
Sunny <me@darkowlzz.space>
|
||||||
Suyash <dextrous93@gmail.com>
|
Suyash <dextrous93@gmail.com>
|
||||||
Suzy Mueller <suzmue@golang.org>
|
Suzy Mueller <suzmue@golang.org>
|
||||||
Sven Almgren <sven@tras.se>
|
Sven Almgren <sven@tras.se>
|
||||||
Sven Blumenstein <svbl@google.com>
|
Sven Blumenstein <svbl@google.com>
|
||||||
|
Sylvain Zimmer <sylvain@sylvainzimmer.com>
|
||||||
Syohei YOSHIDA <syohex@gmail.com>
|
Syohei YOSHIDA <syohex@gmail.com>
|
||||||
Szabolcs Nagy <nsz@port70.net>
|
Szabolcs Nagy <nsz@port70.net>
|
||||||
|
Tad Fisher <tadfisher@gmail.com>
|
||||||
Tad Glines <tad.glines@gmail.com>
|
Tad Glines <tad.glines@gmail.com>
|
||||||
Taj Khattra <taj.khattra@gmail.com>
|
Taj Khattra <taj.khattra@gmail.com>
|
||||||
Takashi Matsuo <tmatsuo@google.com>
|
Takashi Matsuo <tmatsuo@google.com>
|
||||||
|
|
@ -1303,15 +1448,18 @@ Takuto Ikuta <tikuta@google.com>
|
||||||
Takuya Ueda <uedatakuya@gmail.com>
|
Takuya Ueda <uedatakuya@gmail.com>
|
||||||
Tal Shprecher <tshprecher@gmail.com>
|
Tal Shprecher <tshprecher@gmail.com>
|
||||||
Tamir Duberstein <tamird@gmail.com>
|
Tamir Duberstein <tamird@gmail.com>
|
||||||
|
Tao Wang <twang2218@gmail.com>
|
||||||
Tarmigan Casebolt <tarmigan@gmail.com>
|
Tarmigan Casebolt <tarmigan@gmail.com>
|
||||||
Taro Aoki <aizu.s1230022@gmail.com>
|
Taro Aoki <aizu.s1230022@gmail.com>
|
||||||
Taru Karttunen <taruti@taruti.net>
|
Taru Karttunen <taruti@taruti.net>
|
||||||
Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
|
Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
|
||||||
Ted Kornish <golang@tedkornish.com>
|
Ted Kornish <golang@tedkornish.com>
|
||||||
|
Terin Stock <terinjokes@gmail.com>
|
||||||
Terrel Shumway <gopher@shumway.us>
|
Terrel Shumway <gopher@shumway.us>
|
||||||
Tetsuo Kiso <tetsuokiso9@gmail.com>
|
Tetsuo Kiso <tetsuokiso9@gmail.com>
|
||||||
Than McIntosh <thanm@google.com>
|
Than McIntosh <thanm@google.com>
|
||||||
Thanatat Tamtan <acoshift@gmail.com>
|
Thanatat Tamtan <acoshift@gmail.com>
|
||||||
|
Thiago Avelino <t@avelino.xxx>
|
||||||
Thiago Fransosi Farina <thiago.farina@gmail.com> <tfarina@chromium.org>
|
Thiago Fransosi Farina <thiago.farina@gmail.com> <tfarina@chromium.org>
|
||||||
Thomas Alan Copeland <talan.copeland@gmail.com>
|
Thomas Alan Copeland <talan.copeland@gmail.com>
|
||||||
Thomas Bonfort <thomas.bonfort@gmail.com>
|
Thomas Bonfort <thomas.bonfort@gmail.com>
|
||||||
|
|
@ -1320,19 +1468,23 @@ Thomas de Zeeuw <thomasdezeeuw@gmail.com>
|
||||||
Thomas Desrosiers <thomasdesr@gmail.com>
|
Thomas Desrosiers <thomasdesr@gmail.com>
|
||||||
Thomas Habets <habets@google.com>
|
Thomas Habets <habets@google.com>
|
||||||
Thomas Kappler <tkappler@gmail.com>
|
Thomas Kappler <tkappler@gmail.com>
|
||||||
|
Thomas Wanielista <tomwans@gmail.com>
|
||||||
Thorben Krueger <thorben.krueger@gmail.com>
|
Thorben Krueger <thorben.krueger@gmail.com>
|
||||||
Thordur Bjornsson <thorduri@secnorth.net>
|
Thordur Bjornsson <thorduri@secnorth.net>
|
||||||
Tilman Dilo <tilman.dilo@gmail.com>
|
Tilman Dilo <tilman.dilo@gmail.com>
|
||||||
Tim Cooijmans <timcooijmans@gmail.com>
|
Tim Cooijmans <timcooijmans@gmail.com>
|
||||||
|
Tim Cooper <tim.cooper@layeh.com>
|
||||||
Tim Ebringer <tim.ebringer@gmail.com>
|
Tim Ebringer <tim.ebringer@gmail.com>
|
||||||
Tim Heckman <t@heckman.io>
|
Tim Heckman <t@heckman.io>
|
||||||
Tim Henderson <tim.tadh@gmail.com>
|
Tim Henderson <tim.tadh@gmail.com>
|
||||||
Tim Hockin <thockin@google.com>
|
Tim Hockin <thockin@google.com>
|
||||||
Tim Swast <swast@google.com>
|
Tim Swast <swast@google.com>
|
||||||
|
Tim Wright <tenortim@gmail.com>
|
||||||
Timo Savola <timo.savola@gmail.com>
|
Timo Savola <timo.savola@gmail.com>
|
||||||
Timo Truyts <alkaloid.btx@gmail.com>
|
Timo Truyts <alkaloid.btx@gmail.com>
|
||||||
Timothy Studd <tim@timstudd.com>
|
Timothy Studd <tim@timstudd.com>
|
||||||
Tipp Moseley <tipp@google.com>
|
Tipp Moseley <tipp@google.com>
|
||||||
|
Tobias Assarsson <tobias.assarsson@gmail.com>
|
||||||
Tobias Columbus <tobias.columbus@gmail.com> <tobias.columbus@googlemail.com>
|
Tobias Columbus <tobias.columbus@gmail.com> <tobias.columbus@googlemail.com>
|
||||||
Tobias Klauser <tklauser@distanz.ch>
|
Tobias Klauser <tklauser@distanz.ch>
|
||||||
Toby Burress <kurin@google.com>
|
Toby Burress <kurin@google.com>
|
||||||
|
|
@ -1340,6 +1492,8 @@ Todd Neal <todd@tneal.org>
|
||||||
Todd Wang <toddwang@gmail.com>
|
Todd Wang <toddwang@gmail.com>
|
||||||
Tom Bergan <tombergan@google.com>
|
Tom Bergan <tombergan@google.com>
|
||||||
Tom Heng <zhm20070928@gmail.com>
|
Tom Heng <zhm20070928@gmail.com>
|
||||||
|
Tom Lanyon <tomlanyon@google.com>
|
||||||
|
Tom Levy <tomlevy93@gmail.com>
|
||||||
Tom Linford <tomlinford@gmail.com>
|
Tom Linford <tomlinford@gmail.com>
|
||||||
Tom Szymanski <tgs@google.com>
|
Tom Szymanski <tgs@google.com>
|
||||||
Tom Wilkie <tom@weave.works>
|
Tom Wilkie <tom@weave.works>
|
||||||
|
|
@ -1358,9 +1512,12 @@ Trey Tacon <ttacon@gmail.com>
|
||||||
Tristan Amini <tamini01@ca.ibm.com>
|
Tristan Amini <tamini01@ca.ibm.com>
|
||||||
Tristan Colgate <tcolgate@gmail.com>
|
Tristan Colgate <tcolgate@gmail.com>
|
||||||
Tristan Ooohry <ooohry@gmail.com>
|
Tristan Ooohry <ooohry@gmail.com>
|
||||||
|
Troels Thomsen <troels@thomsen.io>
|
||||||
Trung Nguyen <trung.n.k@gmail.com>
|
Trung Nguyen <trung.n.k@gmail.com>
|
||||||
Tudor Golubenco <tudor.g@gmail.com>
|
Tudor Golubenco <tudor.g@gmail.com>
|
||||||
|
Tugdual Saunier <tugdual.saunier@gmail.com>
|
||||||
Tuo Shan <sturbo89@gmail.com> <shantuo@google.com>
|
Tuo Shan <sturbo89@gmail.com> <shantuo@google.com>
|
||||||
|
Tyler Bui-Palsulich <tpalsulich@google.com>
|
||||||
Tyler Bunnell <tylerbunnell@gmail.com>
|
Tyler Bunnell <tylerbunnell@gmail.com>
|
||||||
Tyler Treat <ttreat31@gmail.com>
|
Tyler Treat <ttreat31@gmail.com>
|
||||||
Tzu-Jung Lee <roylee17@currant.com>
|
Tzu-Jung Lee <roylee17@currant.com>
|
||||||
|
|
@ -1393,10 +1550,13 @@ Wade Simmons <wade@wades.im>
|
||||||
Walter Poupore <wpoupore@google.com>
|
Walter Poupore <wpoupore@google.com>
|
||||||
Wander Lairson Costa <wcosta@mozilla.com>
|
Wander Lairson Costa <wcosta@mozilla.com>
|
||||||
Wedson Almeida Filho <wedsonaf@google.com>
|
Wedson Almeida Filho <wedsonaf@google.com>
|
||||||
|
Wèi Cōngruì <crvv.mail@gmail.com>
|
||||||
Wei Guangjing <vcc.163@gmail.com>
|
Wei Guangjing <vcc.163@gmail.com>
|
||||||
Wei Xiao <wei.xiao@arm.com>
|
Wei Xiao <wei.xiao@arm.com>
|
||||||
Weichao Tang <tevic.tt@gmail.com>
|
Weichao Tang <tevic.tt@gmail.com>
|
||||||
|
Wembley G. Leach, Jr <wembley.gl@gmail.com>
|
||||||
Will Chan <willchan@google.com>
|
Will Chan <willchan@google.com>
|
||||||
|
Will Faught <will.faught@gmail.com>
|
||||||
Will Norris <willnorris@google.com>
|
Will Norris <willnorris@google.com>
|
||||||
Will Storey <will@summercat.com>
|
Will Storey <will@summercat.com>
|
||||||
Willem van der Schyff <willemvds@gmail.com>
|
Willem van der Schyff <willemvds@gmail.com>
|
||||||
|
|
@ -1405,6 +1565,7 @@ William Josephson <wjosephson@gmail.com>
|
||||||
William Orr <will@worrbase.com> <ay1244@gmail.com>
|
William Orr <will@worrbase.com> <ay1244@gmail.com>
|
||||||
Wisdom Omuya <deafgoat@gmail.com>
|
Wisdom Omuya <deafgoat@gmail.com>
|
||||||
Wu Yunzhou <yunzhouwu@gmail.com>
|
Wu Yunzhou <yunzhouwu@gmail.com>
|
||||||
|
Xi Ruoyao <xry23333@gmail.com>
|
||||||
Xia Bin <snyh@snyh.org>
|
Xia Bin <snyh@snyh.org>
|
||||||
Xing Xing <mikespook@gmail.com>
|
Xing Xing <mikespook@gmail.com>
|
||||||
Xu Fei <badgangkiller@gmail.com>
|
Xu Fei <badgangkiller@gmail.com>
|
||||||
|
|
@ -1412,6 +1573,7 @@ Xudong Zhang <felixmelon@gmail.com>
|
||||||
Xuyang Kang <xuyangkang@gmail.com>
|
Xuyang Kang <xuyangkang@gmail.com>
|
||||||
Yan Zou <yzou@google.com>
|
Yan Zou <yzou@google.com>
|
||||||
Yann Kerhervé <yann.kerherve@gmail.com>
|
Yann Kerhervé <yann.kerherve@gmail.com>
|
||||||
|
Yann Salaün <yannsalaun1@gmail.com>
|
||||||
Yao Zhang <lunaria21@gmail.com>
|
Yao Zhang <lunaria21@gmail.com>
|
||||||
Yasha Bubnov <girokompass@gmail.com>
|
Yasha Bubnov <girokompass@gmail.com>
|
||||||
Yasuharu Goto <matope.ono@gmail.com>
|
Yasuharu Goto <matope.ono@gmail.com>
|
||||||
|
|
@ -1423,23 +1585,30 @@ Yo-An Lin <yoanlin93@gmail.com>
|
||||||
Yongjian Xu <i3dmaster@gmail.com>
|
Yongjian Xu <i3dmaster@gmail.com>
|
||||||
Yorman Arias <cixtords@gmail.com>
|
Yorman Arias <cixtords@gmail.com>
|
||||||
Yoshiyuki Kanno <nekotaroh@gmail.com> <yoshiyuki.kanno@stoic.co.jp>
|
Yoshiyuki Kanno <nekotaroh@gmail.com> <yoshiyuki.kanno@stoic.co.jp>
|
||||||
|
Yosuke Akatsuka <yosuke.akatsuka@gmail.com>
|
||||||
Yu Heng Zhang <annita.zhang@cn.ibm.com>
|
Yu Heng Zhang <annita.zhang@cn.ibm.com>
|
||||||
Yu Xuan Zhang <zyxsh@cn.ibm.com>
|
Yu Xuan Zhang <zyxsh@cn.ibm.com>
|
||||||
Yuki Yugui Sonoda <yugui@google.com>
|
Yuki Yugui Sonoda <yugui@google.com>
|
||||||
|
Yukihiro Nishinaka <6elpinal@gmail.com>
|
||||||
Yusuke Kagiwada <block.rxckin.beats@gmail.com>
|
Yusuke Kagiwada <block.rxckin.beats@gmail.com>
|
||||||
Yuusei Kuwana <kuwana@kumama.org>
|
Yuusei Kuwana <kuwana@kumama.org>
|
||||||
Yuval Pavel Zholkover <paulzhol@gmail.com>
|
Yuval Pavel Zholkover <paulzhol@gmail.com>
|
||||||
Yves Junqueira <yvesj@google.com> <yves.junqueira@gmail.com>
|
Yves Junqueira <yvesj@google.com> <yves.junqueira@gmail.com>
|
||||||
Zac Bergquist <zbergquist99@gmail.com>
|
Zac Bergquist <zbergquist99@gmail.com>
|
||||||
Zach Bintliff <zbintliff@gmail.com>
|
Zach Bintliff <zbintliff@gmail.com>
|
||||||
|
Zach Gershman <zachgersh@gmail.com>
|
||||||
Zak <zrjknill@gmail.com>
|
Zak <zrjknill@gmail.com>
|
||||||
Zakatell Kanda <hi@zkanda.io>
|
Zakatell Kanda <hi@zkanda.io>
|
||||||
Zellyn Hunter <zellyn@squareup.com> <zellyn@gmail.com>
|
Zellyn Hunter <zellyn@squareup.com> <zellyn@gmail.com>
|
||||||
Zev Goldstein <zev.goldstein@gmail.com>
|
Zev Goldstein <zev.goldstein@gmail.com>
|
||||||
|
Zhengyu He <hzy@google.com>
|
||||||
|
Zhongtao Chen <chenzhongtao@126.com>
|
||||||
Zhongwei Yao <zhongwei.yao@arm.com>
|
Zhongwei Yao <zhongwei.yao@arm.com>
|
||||||
Ziad Hatahet <hatahet@gmail.com>
|
Ziad Hatahet <hatahet@gmail.com>
|
||||||
Zorion Arrizabalaga <zorionk@gmail.com>
|
Zorion Arrizabalaga <zorionk@gmail.com>
|
||||||
Максим Федосеев <max.faceless.frei@gmail.com>
|
Максим Федосеев <max.faceless.frei@gmail.com>
|
||||||
|
Роман Хавроненко <hagen1778@gmail.com>
|
||||||
|
Тарас Буник <tbunyk@gmail.com>
|
||||||
Фахриддин Балтаев <faxriddinjon@gmail.com>
|
Фахриддин Балтаев <faxriddinjon@gmail.com>
|
||||||
张嵩 <zs349596@gmail.com>
|
张嵩 <zs349596@gmail.com>
|
||||||
申习之 <bronze1man@gmail.com>
|
申习之 <bronze1man@gmail.com>
|
||||||
|
|
|
||||||
|
|
@ -31,15 +31,14 @@ in your web browser for source installation instructions.
|
||||||
|
|
||||||
### Contributing
|
### Contributing
|
||||||
|
|
||||||
Go is the work of hundreds of contributors. We appreciate your help!
|
Go is the work of thousands of contributors. We appreciate your help!
|
||||||
|
|
||||||
To contribute, please read the contribution guidelines:
|
To contribute, please read the contribution guidelines:
|
||||||
https://golang.org/doc/contribute.html
|
https://golang.org/doc/contribute.html
|
||||||
|
|
||||||
Note that the Go project does not use GitHub pull requests, and that
|
Note that the Go project uses the issue tracker for bug reports and
|
||||||
we use the issue tracker for bug reports and proposals only. See
|
proposals only. See https://golang.org/wiki/Questions for a list of
|
||||||
https://golang.org/wiki/Questions for a list of places to ask
|
places to ask questions about the Go language.
|
||||||
questions about the Go language.
|
|
||||||
|
|
||||||
[rf]: https://reneefrench.blogspot.com/
|
[rf]: https://reneefrench.blogspot.com/
|
||||||
[cc3-by]: https://creativecommons.org/licenses/by/3.0/
|
[cc3-by]: https://creativecommons.org/licenses/by/3.0/
|
||||||
|
|
|
||||||
|
|
@ -11,4 +11,3 @@ compatibility.
|
||||||
next.txt is the only file intended to be mutated. It's a list of
|
next.txt is the only file intended to be mutated. It's a list of
|
||||||
features that may be added to the next version. It only affects
|
features that may be added to the next version. It only affects
|
||||||
warning output from the go api tool.
|
warning output from the go api tool.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ pkg encoding/json, method (*RawMessage) MarshalJSON() ([]uint8, error)
|
||||||
pkg math/big, const MaxBase = 36
|
pkg math/big, const MaxBase = 36
|
||||||
pkg math/big, type Word uintptr
|
pkg math/big, type Word uintptr
|
||||||
pkg net, func ListenUnixgram(string, *UnixAddr) (*UDPConn, error)
|
pkg net, func ListenUnixgram(string, *UnixAddr) (*UDPConn, error)
|
||||||
|
pkg os, const ModeType = 2399141888
|
||||||
pkg os (linux-arm), const O_SYNC = 4096
|
pkg os (linux-arm), const O_SYNC = 4096
|
||||||
pkg os (linux-arm-cgo), const O_SYNC = 4096
|
pkg os (linux-arm-cgo), const O_SYNC = 4096
|
||||||
pkg syscall (darwin-386), const ImplementsGetwd = false
|
pkg syscall (darwin-386), const ImplementsGetwd = false
|
||||||
|
|
@ -15,25 +16,30 @@ pkg syscall (darwin-amd64-cgo), func Fchflags(string, int) error
|
||||||
pkg syscall (freebsd-386), const AF_MAX = 38
|
pkg syscall (freebsd-386), const AF_MAX = 38
|
||||||
pkg syscall (freebsd-386), const DLT_MATCHING_MAX = 242
|
pkg syscall (freebsd-386), const DLT_MATCHING_MAX = 242
|
||||||
pkg syscall (freebsd-386), const ELAST = 94
|
pkg syscall (freebsd-386), const ELAST = 94
|
||||||
|
pkg syscall (freebsd-386), const ImplementsGetwd = false
|
||||||
pkg syscall (freebsd-386), const O_CLOEXEC = 0
|
pkg syscall (freebsd-386), const O_CLOEXEC = 0
|
||||||
pkg syscall (freebsd-386), func Fchflags(string, int) error
|
pkg syscall (freebsd-386), func Fchflags(string, int) error
|
||||||
pkg syscall (freebsd-386-cgo), const AF_MAX = 38
|
pkg syscall (freebsd-386-cgo), const AF_MAX = 38
|
||||||
pkg syscall (freebsd-386-cgo), const DLT_MATCHING_MAX = 242
|
pkg syscall (freebsd-386-cgo), const DLT_MATCHING_MAX = 242
|
||||||
pkg syscall (freebsd-386-cgo), const ELAST = 94
|
pkg syscall (freebsd-386-cgo), const ELAST = 94
|
||||||
|
pkg syscall (freebsd-386-cgo), const ImplementsGetwd = false
|
||||||
pkg syscall (freebsd-386-cgo), const O_CLOEXEC = 0
|
pkg syscall (freebsd-386-cgo), const O_CLOEXEC = 0
|
||||||
pkg syscall (freebsd-amd64), const AF_MAX = 38
|
pkg syscall (freebsd-amd64), const AF_MAX = 38
|
||||||
pkg syscall (freebsd-amd64), const DLT_MATCHING_MAX = 242
|
pkg syscall (freebsd-amd64), const DLT_MATCHING_MAX = 242
|
||||||
pkg syscall (freebsd-amd64), const ELAST = 94
|
pkg syscall (freebsd-amd64), const ELAST = 94
|
||||||
|
pkg syscall (freebsd-amd64), const ImplementsGetwd = false
|
||||||
pkg syscall (freebsd-amd64), const O_CLOEXEC = 0
|
pkg syscall (freebsd-amd64), const O_CLOEXEC = 0
|
||||||
pkg syscall (freebsd-amd64), func Fchflags(string, int) error
|
pkg syscall (freebsd-amd64), func Fchflags(string, int) error
|
||||||
pkg syscall (freebsd-amd64-cgo), const AF_MAX = 38
|
pkg syscall (freebsd-amd64-cgo), const AF_MAX = 38
|
||||||
pkg syscall (freebsd-amd64-cgo), const DLT_MATCHING_MAX = 242
|
pkg syscall (freebsd-amd64-cgo), const DLT_MATCHING_MAX = 242
|
||||||
pkg syscall (freebsd-amd64-cgo), const ELAST = 94
|
pkg syscall (freebsd-amd64-cgo), const ELAST = 94
|
||||||
|
pkg syscall (freebsd-amd64-cgo), const ImplementsGetwd = false
|
||||||
pkg syscall (freebsd-amd64-cgo), const O_CLOEXEC = 0
|
pkg syscall (freebsd-amd64-cgo), const O_CLOEXEC = 0
|
||||||
pkg syscall (freebsd-arm), const AF_MAX = 38
|
pkg syscall (freebsd-arm), const AF_MAX = 38
|
||||||
pkg syscall (freebsd-arm), const BIOCGRTIMEOUT = 1074545262
|
pkg syscall (freebsd-arm), const BIOCGRTIMEOUT = 1074545262
|
||||||
pkg syscall (freebsd-arm), const BIOCSRTIMEOUT = 2148287085
|
pkg syscall (freebsd-arm), const BIOCSRTIMEOUT = 2148287085
|
||||||
pkg syscall (freebsd-arm), const ELAST = 94
|
pkg syscall (freebsd-arm), const ELAST = 94
|
||||||
|
pkg syscall (freebsd-arm), const ImplementsGetwd = false
|
||||||
pkg syscall (freebsd-arm), const O_CLOEXEC = 0
|
pkg syscall (freebsd-arm), const O_CLOEXEC = 0
|
||||||
pkg syscall (freebsd-arm), const SIOCAIFADDR = 2151967019
|
pkg syscall (freebsd-arm), const SIOCAIFADDR = 2151967019
|
||||||
pkg syscall (freebsd-arm), const SIOCGIFSTATUS = 3274991931
|
pkg syscall (freebsd-arm), const SIOCGIFSTATUS = 3274991931
|
||||||
|
|
@ -65,6 +71,7 @@ pkg syscall (freebsd-arm-cgo), const AF_MAX = 38
|
||||||
pkg syscall (freebsd-arm-cgo), const BIOCGRTIMEOUT = 1074545262
|
pkg syscall (freebsd-arm-cgo), const BIOCGRTIMEOUT = 1074545262
|
||||||
pkg syscall (freebsd-arm-cgo), const BIOCSRTIMEOUT = 2148287085
|
pkg syscall (freebsd-arm-cgo), const BIOCSRTIMEOUT = 2148287085
|
||||||
pkg syscall (freebsd-arm-cgo), const ELAST = 94
|
pkg syscall (freebsd-arm-cgo), const ELAST = 94
|
||||||
|
pkg syscall (freebsd-arm-cgo), const ImplementsGetwd = false
|
||||||
pkg syscall (freebsd-arm-cgo), const O_CLOEXEC = 0
|
pkg syscall (freebsd-arm-cgo), const O_CLOEXEC = 0
|
||||||
pkg syscall (freebsd-arm-cgo), const SIOCAIFADDR = 2151967019
|
pkg syscall (freebsd-arm-cgo), const SIOCAIFADDR = 2151967019
|
||||||
pkg syscall (freebsd-arm-cgo), const SIOCGIFSTATUS = 3274991931
|
pkg syscall (freebsd-arm-cgo), const SIOCGIFSTATUS = 3274991931
|
||||||
|
|
@ -98,6 +105,12 @@ pkg syscall (linux-amd64), type Cmsghdr struct, X__cmsg_data [0]uint8
|
||||||
pkg syscall (linux-amd64-cgo), type Cmsghdr struct, X__cmsg_data [0]uint8
|
pkg syscall (linux-amd64-cgo), type Cmsghdr struct, X__cmsg_data [0]uint8
|
||||||
pkg syscall (linux-arm), type Cmsghdr struct, X__cmsg_data [0]uint8
|
pkg syscall (linux-arm), type Cmsghdr struct, X__cmsg_data [0]uint8
|
||||||
pkg syscall (linux-arm-cgo), type Cmsghdr struct, X__cmsg_data [0]uint8
|
pkg syscall (linux-arm-cgo), type Cmsghdr struct, X__cmsg_data [0]uint8
|
||||||
|
pkg syscall (netbsd-386), const ImplementsGetwd = false
|
||||||
|
pkg syscall (netbsd-386-cgo), const ImplementsGetwd = false
|
||||||
|
pkg syscall (netbsd-amd64), const ImplementsGetwd = false
|
||||||
|
pkg syscall (netbsd-amd64-cgo), const ImplementsGetwd = false
|
||||||
|
pkg syscall (netbsd-arm), const ImplementsGetwd = false
|
||||||
|
pkg syscall (netbsd-arm-cgo), const ImplementsGetwd = false
|
||||||
pkg syscall (netbsd-arm), const SizeofIfData = 132
|
pkg syscall (netbsd-arm), const SizeofIfData = 132
|
||||||
pkg syscall (netbsd-arm), func Fchflags(string, int) error
|
pkg syscall (netbsd-arm), func Fchflags(string, int) error
|
||||||
pkg syscall (netbsd-arm), type IfMsghdr struct, Pad_cgo_1 [4]uint8
|
pkg syscall (netbsd-arm), type IfMsghdr struct, Pad_cgo_1 [4]uint8
|
||||||
|
|
@ -106,6 +119,7 @@ pkg syscall (netbsd-arm-cgo), func Fchflags(string, int) error
|
||||||
pkg syscall (netbsd-arm-cgo), type IfMsghdr struct, Pad_cgo_1 [4]uint8
|
pkg syscall (netbsd-arm-cgo), type IfMsghdr struct, Pad_cgo_1 [4]uint8
|
||||||
pkg syscall (openbsd-386), const BIOCGRTIMEOUT = 1074283118
|
pkg syscall (openbsd-386), const BIOCGRTIMEOUT = 1074283118
|
||||||
pkg syscall (openbsd-386), const BIOCSRTIMEOUT = 2148024941
|
pkg syscall (openbsd-386), const BIOCSRTIMEOUT = 2148024941
|
||||||
|
pkg syscall (openbsd-386), const ImplementsGetwd = false
|
||||||
pkg syscall (openbsd-386), const RTF_FMASK = 63496
|
pkg syscall (openbsd-386), const RTF_FMASK = 63496
|
||||||
pkg syscall (openbsd-386), const RTM_VERSION = 4
|
pkg syscall (openbsd-386), const RTM_VERSION = 4
|
||||||
pkg syscall (openbsd-386), const SIOCBRDGDADDR = 2150132039
|
pkg syscall (openbsd-386), const SIOCBRDGDADDR = 2150132039
|
||||||
|
|
@ -158,6 +172,7 @@ pkg syscall (openbsd-386), type Timespec struct, Sec int32
|
||||||
pkg syscall (openbsd-386), type Timeval struct, Sec int32
|
pkg syscall (openbsd-386), type Timeval struct, Sec int32
|
||||||
pkg syscall (openbsd-386-cgo), const BIOCGRTIMEOUT = 1074283118
|
pkg syscall (openbsd-386-cgo), const BIOCGRTIMEOUT = 1074283118
|
||||||
pkg syscall (openbsd-386-cgo), const BIOCSRTIMEOUT = 2148024941
|
pkg syscall (openbsd-386-cgo), const BIOCSRTIMEOUT = 2148024941
|
||||||
|
pkg syscall (openbsd-386-cgo), const ImplementsGetwd = false
|
||||||
pkg syscall (openbsd-386-cgo), const RTF_FMASK = 63496
|
pkg syscall (openbsd-386-cgo), const RTF_FMASK = 63496
|
||||||
pkg syscall (openbsd-386-cgo), const RTM_VERSION = 4
|
pkg syscall (openbsd-386-cgo), const RTM_VERSION = 4
|
||||||
pkg syscall (openbsd-386-cgo), const SIOCBRDGDADDR = 2150132039
|
pkg syscall (openbsd-386-cgo), const SIOCBRDGDADDR = 2150132039
|
||||||
|
|
@ -220,6 +235,7 @@ pkg syscall (openbsd-amd64), const EFER_NXE = 2048
|
||||||
pkg syscall (openbsd-amd64), const EFER_NXE ideal-int
|
pkg syscall (openbsd-amd64), const EFER_NXE ideal-int
|
||||||
pkg syscall (openbsd-amd64), const EFER_SCE = 1
|
pkg syscall (openbsd-amd64), const EFER_SCE = 1
|
||||||
pkg syscall (openbsd-amd64), const EFER_SCE ideal-int
|
pkg syscall (openbsd-amd64), const EFER_SCE ideal-int
|
||||||
|
pkg syscall (openbsd-amd64), const ImplementsGetwd = false
|
||||||
pkg syscall (openbsd-amd64), const PMC5_PIPELINE_FLUSH = 21
|
pkg syscall (openbsd-amd64), const PMC5_PIPELINE_FLUSH = 21
|
||||||
pkg syscall (openbsd-amd64), const PMC5_PIPELINE_FLUSH ideal-int
|
pkg syscall (openbsd-amd64), const PMC5_PIPELINE_FLUSH ideal-int
|
||||||
pkg syscall (openbsd-amd64), const RTF_FMASK = 63496
|
pkg syscall (openbsd-amd64), const RTF_FMASK = 63496
|
||||||
|
|
@ -282,6 +298,7 @@ pkg syscall (openbsd-amd64-cgo), const EFER_NXE = 2048
|
||||||
pkg syscall (openbsd-amd64-cgo), const EFER_NXE ideal-int
|
pkg syscall (openbsd-amd64-cgo), const EFER_NXE ideal-int
|
||||||
pkg syscall (openbsd-amd64-cgo), const EFER_SCE = 1
|
pkg syscall (openbsd-amd64-cgo), const EFER_SCE = 1
|
||||||
pkg syscall (openbsd-amd64-cgo), const EFER_SCE ideal-int
|
pkg syscall (openbsd-amd64-cgo), const EFER_SCE ideal-int
|
||||||
|
pkg syscall (openbsd-amd64-cgo), const ImplementsGetwd = false
|
||||||
pkg syscall (openbsd-amd64-cgo), const PMC5_PIPELINE_FLUSH = 21
|
pkg syscall (openbsd-amd64-cgo), const PMC5_PIPELINE_FLUSH = 21
|
||||||
pkg syscall (openbsd-amd64-cgo), const PMC5_PIPELINE_FLUSH ideal-int
|
pkg syscall (openbsd-amd64-cgo), const PMC5_PIPELINE_FLUSH ideal-int
|
||||||
pkg syscall (openbsd-amd64-cgo), const RTF_FMASK = 63496
|
pkg syscall (openbsd-amd64-cgo), const RTF_FMASK = 63496
|
||||||
|
|
@ -345,3 +362,24 @@ pkg syscall (openbsd-386-cgo), const SYS_KILL = 37
|
||||||
pkg syscall (openbsd-amd64), const SYS_KILL = 37
|
pkg syscall (openbsd-amd64), const SYS_KILL = 37
|
||||||
pkg syscall (openbsd-amd64-cgo), const SYS_KILL = 37
|
pkg syscall (openbsd-amd64-cgo), const SYS_KILL = 37
|
||||||
pkg unicode, const Version = "9.0.0"
|
pkg unicode, const Version = "9.0.0"
|
||||||
|
pkg text/template/parse, method (*VariableNode) Copy() Node
|
||||||
|
pkg text/template/parse, method (*VariableNode) String() string
|
||||||
|
pkg text/template/parse, method (VariableNode) Position() Pos
|
||||||
|
pkg text/template/parse, method (VariableNode) Type() NodeType
|
||||||
|
pkg text/template/parse, type PipeNode struct, Decl []*VariableNode
|
||||||
|
pkg text/template/parse, type VariableNode struct
|
||||||
|
pkg text/template/parse, type VariableNode struct, Ident []string
|
||||||
|
pkg text/template/parse, type VariableNode struct, embedded NodeType
|
||||||
|
pkg text/template/parse, type VariableNode struct, embedded Pos
|
||||||
|
pkg syscall (windows-386), type CertChainPolicyPara struct, ExtraPolicyPara uintptr
|
||||||
|
pkg syscall (windows-386), type CertChainPolicyStatus struct, ExtraPolicyStatus uintptr
|
||||||
|
pkg syscall (windows-386), type CertContext struct, CertInfo uintptr
|
||||||
|
pkg syscall (windows-386), type CertRevocationInfo struct, CrlInfo uintptr
|
||||||
|
pkg syscall (windows-386), type CertRevocationInfo struct, OidSpecificInfo uintptr
|
||||||
|
pkg syscall (windows-386), type CertSimpleChain struct, TrustListInfo uintptr
|
||||||
|
pkg syscall (windows-amd64), type CertChainPolicyPara struct, ExtraPolicyPara uintptr
|
||||||
|
pkg syscall (windows-amd64), type CertChainPolicyStatus struct, ExtraPolicyStatus uintptr
|
||||||
|
pkg syscall (windows-amd64), type CertContext struct, CertInfo uintptr
|
||||||
|
pkg syscall (windows-amd64), type CertRevocationInfo struct, CrlInfo uintptr
|
||||||
|
pkg syscall (windows-amd64), type CertRevocationInfo struct, OidSpecificInfo uintptr
|
||||||
|
pkg syscall (windows-amd64), type CertSimpleChain struct, TrustListInfo uintptr
|
||||||
|
|
|
||||||
|
|
@ -573,6 +573,7 @@ pkg encoding/xml, type TokenReader interface, Token() (Token, error)
|
||||||
pkg flag, method (*FlagSet) ErrorHandling() ErrorHandling
|
pkg flag, method (*FlagSet) ErrorHandling() ErrorHandling
|
||||||
pkg flag, method (*FlagSet) Name() string
|
pkg flag, method (*FlagSet) Name() string
|
||||||
pkg flag, method (*FlagSet) Output() io.Writer
|
pkg flag, method (*FlagSet) Output() io.Writer
|
||||||
|
pkg html/template, type Srcset string
|
||||||
pkg math, func Erfcinv(float64) float64
|
pkg math, func Erfcinv(float64) float64
|
||||||
pkg math, func Erfinv(float64) float64
|
pkg math, func Erfinv(float64) float64
|
||||||
pkg math, func Round(float64) float64
|
pkg math, func Round(float64) float64
|
||||||
|
|
@ -594,7 +595,6 @@ pkg os, method (*SyscallError) Timeout() bool
|
||||||
pkg os, var ErrNoDeadline error
|
pkg os, var ErrNoDeadline error
|
||||||
pkg strings, method (*Builder) Grow(int)
|
pkg strings, method (*Builder) Grow(int)
|
||||||
pkg strings, method (*Builder) Len() int
|
pkg strings, method (*Builder) Len() int
|
||||||
pkg strings, method (*Builder) ReadFrom(io.Reader) (int64, error)
|
|
||||||
pkg strings, method (*Builder) Reset()
|
pkg strings, method (*Builder) Reset()
|
||||||
pkg strings, method (*Builder) String() string
|
pkg strings, method (*Builder) String() string
|
||||||
pkg strings, method (*Builder) Write([]uint8) (int, error)
|
pkg strings, method (*Builder) Write([]uint8) (int, error)
|
||||||
|
|
@ -618,24 +618,6 @@ pkg syscall (windows-386), func CreateProcessAsUser(Token, *uint16, *uint16, *Se
|
||||||
pkg syscall (windows-386), type SysProcAttr struct, Token Token
|
pkg syscall (windows-386), type SysProcAttr struct, Token Token
|
||||||
pkg syscall (windows-amd64), func CreateProcessAsUser(Token, *uint16, *uint16, *SecurityAttributes, *SecurityAttributes, bool, uint32, *uint16, *uint16, *StartupInfo, *ProcessInformation) error
|
pkg syscall (windows-amd64), func CreateProcessAsUser(Token, *uint16, *uint16, *SecurityAttributes, *SecurityAttributes, bool, uint32, *uint16, *uint16, *StartupInfo, *ProcessInformation) error
|
||||||
pkg syscall (windows-amd64), type SysProcAttr struct, Token Token
|
pkg syscall (windows-amd64), type SysProcAttr struct, Token Token
|
||||||
pkg text/template/parse, const NodeBreak = 20
|
|
||||||
pkg text/template/parse, const NodeBreak NodeType
|
|
||||||
pkg text/template/parse, const NodeContinue = 21
|
|
||||||
pkg text/template/parse, const NodeContinue NodeType
|
|
||||||
pkg text/template/parse, method (*BreakNode) Copy() Node
|
|
||||||
pkg text/template/parse, method (*BreakNode) Position() Pos
|
|
||||||
pkg text/template/parse, method (*BreakNode) String() string
|
|
||||||
pkg text/template/parse, method (*BreakNode) Type() NodeType
|
|
||||||
pkg text/template/parse, method (*ContinueNode) Copy() Node
|
|
||||||
pkg text/template/parse, method (*ContinueNode) Position() Pos
|
|
||||||
pkg text/template/parse, method (*ContinueNode) String() string
|
|
||||||
pkg text/template/parse, method (*ContinueNode) Type() NodeType
|
|
||||||
pkg text/template/parse, type BreakNode struct
|
|
||||||
pkg text/template/parse, type BreakNode struct, embedded NodeType
|
|
||||||
pkg text/template/parse, type BreakNode struct, embedded Pos
|
|
||||||
pkg text/template/parse, type ContinueNode struct
|
|
||||||
pkg text/template/parse, type ContinueNode struct, embedded NodeType
|
|
||||||
pkg text/template/parse, type ContinueNode struct, embedded Pos
|
|
||||||
pkg time, func LoadLocationFromTZData(string, []uint8) (*Location, error)
|
pkg time, func LoadLocationFromTZData(string, []uint8) (*Location, error)
|
||||||
pkg unicode, const Version = "10.0.0"
|
pkg unicode, const Version = "10.0.0"
|
||||||
pkg unicode, var Masaram_Gondi *RangeTable
|
pkg unicode, var Masaram_Gondi *RangeTable
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,7 @@ be able to adapt to changing build environments and conditions. For
|
||||||
example, if we allowed extra configuration such as compiler flags or
|
example, if we allowed extra configuration such as compiler flags or
|
||||||
command line recipes, then that configuration would need to be updated
|
command line recipes, then that configuration would need to be updated
|
||||||
each time the build tools changed; it would also be inherently tied
|
each time the build tools changed; it would also be inherently tied
|
||||||
to the use of a specific tool chain.</p>
|
to the use of a specific toolchain.</p>
|
||||||
|
|
||||||
<h2>Getting started with the go command</h2>
|
<h2>Getting started with the go command</h2>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -268,6 +268,12 @@ view a wiki page. It will handle URLs prefixed with "/view/".
|
||||||
|
|
||||||
{{code "doc/articles/wiki/part2.go" `/^func viewHandler/` `/^}/`}}
|
{{code "doc/articles/wiki/part2.go" `/^func viewHandler/` `/^}/`}}
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Again, note the use of <code>_</code> to ignore the <code>error</code>
|
||||||
|
return value from <code>loadPage</code>. This is done here for simplicity
|
||||||
|
and generally considered bad practice. We will attend to this later.
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
First, this function extracts the page title from <code>r.URL.Path</code>,
|
First, this function extracts the page title from <code>r.URL.Path</code>,
|
||||||
the path component of the request URL.
|
the path component of the request URL.
|
||||||
|
|
@ -282,12 +288,6 @@ The function then loads the page data, formats the page with a string of simple
|
||||||
HTML, and writes it to <code>w</code>, the <code>http.ResponseWriter</code>.
|
HTML, and writes it to <code>w</code>, the <code>http.ResponseWriter</code>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
|
||||||
Again, note the use of <code>_</code> to ignore the <code>error</code>
|
|
||||||
return value from <code>loadPage</code>. This is done here for simplicity
|
|
||||||
and generally considered bad practice. We will attend to this later.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
To use this handler, we rewrite our <code>main</code> function to
|
To use this handler, we rewrite our <code>main</code> function to
|
||||||
initialize <code>http</code> using the <code>viewHandler</code> to handle
|
initialize <code>http</code> using the <code>viewHandler</code> to handle
|
||||||
|
|
|
||||||
69
doc/asm.html
69
doc/asm.html
|
|
@ -29,7 +29,7 @@ Instead, the compiler operates on a kind of semi-abstract instruction set,
|
||||||
and instruction selection occurs partly after code generation.
|
and instruction selection occurs partly after code generation.
|
||||||
The assembler works on the semi-abstract form, so
|
The assembler works on the semi-abstract form, so
|
||||||
when you see an instruction like <code>MOV</code>
|
when you see an instruction like <code>MOV</code>
|
||||||
what the tool chain actually generates for that operation might
|
what the toolchain actually generates for that operation might
|
||||||
not be a move instruction at all, perhaps a clear or load.
|
not be a move instruction at all, perhaps a clear or load.
|
||||||
Or it might correspond exactly to the machine instruction with that name.
|
Or it might correspond exactly to the machine instruction with that name.
|
||||||
In general, machine-specific operations tend to appear as themselves, while more general concepts like
|
In general, machine-specific operations tend to appear as themselves, while more general concepts like
|
||||||
|
|
@ -139,7 +139,7 @@ The exact set depends on the architecture.
|
||||||
<p>
|
<p>
|
||||||
There are four predeclared symbols that refer to pseudo-registers.
|
There are four predeclared symbols that refer to pseudo-registers.
|
||||||
These are not real registers, but rather virtual registers maintained by
|
These are not real registers, but rather virtual registers maintained by
|
||||||
the tool chain, such as a frame pointer.
|
the toolchain, such as a frame pointer.
|
||||||
The set of pseudo-registers is the same for all architectures:
|
The set of pseudo-registers is the same for all architectures:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
@ -738,6 +738,13 @@ The other codes are <code>-></code> (arithmetic right shift),
|
||||||
The ARM64 port is in an experimental state.
|
The ARM64 port is in an experimental state.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<code>R18</code> is the "platform register", reserved on the Apple platform.
|
||||||
|
<code>R27</code> and <code>R28</code> are reserved by the compiler and linker.
|
||||||
|
<code>R29</code> is the frame pointer.
|
||||||
|
<code>R30</code> is the link register.
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Instruction modifiers are appended to the instruction following a period.
|
Instruction modifiers are appended to the instruction following a period.
|
||||||
The only modifiers are <code>P</code> (postincrement) and <code>W</code>
|
The only modifiers are <code>P</code> (postincrement) and <code>W</code>
|
||||||
|
|
@ -752,11 +759,61 @@ Addressing modes:
|
||||||
<ul>
|
<ul>
|
||||||
|
|
||||||
<li>
|
<li>
|
||||||
<code>(R5, R6)</code>: Register pair for <code>LDP</code>/<code>STP</code>.
|
<code>R0->16</code>
|
||||||
|
<br>
|
||||||
|
<code>R0>>16</code>
|
||||||
|
<br>
|
||||||
|
<code>R0<<16</code>
|
||||||
|
<br>
|
||||||
|
<code>R0@>16</code>:
|
||||||
|
These are the same as on the 32-bit ARM.
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<code>$(8<<12)</code>:
|
||||||
|
Left shift the immediate value <code>8</code> by <code>12</code> bits.
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<code>8(R0)</code>:
|
||||||
|
Add the value of <code>R0</code> and <code>8</code>.
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<code>(R2)(R0)</code>:
|
||||||
|
The location at <code>R0</code> plus <code>R2</code>.
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<code>R0.UXTB</code>
|
||||||
|
<br>
|
||||||
|
<code>R0.UXTB<<imm</code>:
|
||||||
|
<code>UXTB</code>: extract an 8-bit value from the low-order bits of <code>R0</code> and zero-extend it to the size of <code>R0</code>.
|
||||||
|
<code>R0.UXTB<<imm</code>: left shift the result of <code>R0.UXTB</code> by <code>imm</code> bits.
|
||||||
|
The <code>imm</code> value can be 0, 1, 2, 3, or 4.
|
||||||
|
The other extensions include <code>UXTH</code> (16-bit), <code>UXTW</code> (32-bit), and <code>UXTX</code> (64-bit).
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<code>R0.SXTB</code>
|
||||||
|
<br>
|
||||||
|
<code>R0.SXTB<<imm</code>:
|
||||||
|
<code>SXTB</code>: extract an 8-bit value from the low-order bits of <code>R0</code> and sign-extend it to the size of <code>R0</code>.
|
||||||
|
<code>R0.SXTB<<imm</code>: left shift the result of <code>R0.SXTB</code> by <code>imm</code> bits.
|
||||||
|
The <code>imm</code> value can be 0, 1, 2, 3, or 4.
|
||||||
|
The other extensions include <code>SXTH</code> (16-bit), <code>SXTW</code> (32-bit), and <code>SXTX</code> (64-bit).
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<code>(R5, R6)</code>: Register pair for <code>LDAXP</code>/<code>LDP</code>/<code>LDXP</code>/<code>STLXP</code>/<code>STP</code>/<code>STP</code>.
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Reference: <a href="/pkg/cmd/internal/obj/arm64">Go ARM64 Assembly Instructions Reference Manual</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
<h3 id="ppc64">64-bit PowerPC, a.k.a. ppc64</h3>
|
<h3 id="ppc64">64-bit PowerPC, a.k.a. ppc64</h3>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -882,6 +939,12 @@ The value of <code>GOMIPS</code> environment variable (<code>hardfloat</code> or
|
||||||
<code>GOMIPS_hardfloat</code> or <code>GOMIPS_softfloat</code>.
|
<code>GOMIPS_hardfloat</code> or <code>GOMIPS_softfloat</code>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The value of <code>GOMIPS64</code> environment variable (<code>hardfloat</code> or
|
||||||
|
<code>softfloat</code>) is made available to assembly code by predefining either
|
||||||
|
<code>GOMIPS64_hardfloat</code> or <code>GOMIPS64_softfloat</code>.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h3 id="unsupported_opcodes">Unsupported opcodes</h3>
|
<h3 id="unsupported_opcodes">Unsupported opcodes</h3>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
|
||||||
|
|
@ -183,7 +183,6 @@ satisfaction of all parties. They are:
|
||||||
<li>Aditya Mukerjee <dev@chimeracoder.net>
|
<li>Aditya Mukerjee <dev@chimeracoder.net>
|
||||||
<li>Andrew Gerrand <adg@golang.org>
|
<li>Andrew Gerrand <adg@golang.org>
|
||||||
<li>Peggy Li <peggyli.224@gmail.com>
|
<li>Peggy Li <peggyli.224@gmail.com>
|
||||||
<li>Sarah Adams <sadams.codes@gmail.com>
|
|
||||||
<li>Steve Francia <steve.francia@gmail.com>
|
<li>Steve Francia <steve.francia@gmail.com>
|
||||||
<li>Verónica López <gveronicalg@gmail.com>
|
<li>Verónica López <gveronicalg@gmail.com>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
||||||
|
|
@ -118,6 +118,6 @@ guidelines</a> for information on design, testing, and our code review process.
|
||||||
<p>
|
<p>
|
||||||
Check <a href="//golang.org/issue">the tracker</a> for
|
Check <a href="//golang.org/issue">the tracker</a> for
|
||||||
open issues that interest you. Those labeled
|
open issues that interest you. Those labeled
|
||||||
<a href="https://github.com/golang/go/issues?q=is%3Aopen+is%3Aissue+label%3Ahelpwanted">helpwanted</a>
|
<a href="https://github.com/golang/go/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22">help wanted</a>
|
||||||
are particularly in need of outside help.
|
are particularly in need of outside help.
|
||||||
</p>
|
</p>
|
||||||
|
|
|
||||||
1780
doc/contribute.html
1780
doc/contribute.html
File diff suppressed because it is too large
Load diff
|
|
@ -3,28 +3,54 @@
|
||||||
"Path": "/doc/gdb"
|
"Path": "/doc/gdb"
|
||||||
}-->
|
}-->
|
||||||
|
|
||||||
<p><i>
|
<!--
|
||||||
This applies to the standard toolchain (the <code>gc</code> Go
|
NOTE: In this document and others in this directory, the convention is to
|
||||||
compiler and tools). Gccgo has native gdb support.
|
set fixed-width phrases with non-fixed-width spaces, as in
|
||||||
Besides this overview you might want to consult the
|
<code>hello</code> <code>world</code>.
|
||||||
<a href="http://sourceware.org/gdb/current/onlinedocs/gdb/">GDB manual</a>.
|
Do not send CLs removing the interior tags from such phrases.
|
||||||
</i></p>
|
-->
|
||||||
|
|
||||||
|
<i>
|
||||||
|
<p>
|
||||||
|
The following instructions apply to the standard toolchain
|
||||||
|
(the <code>gc</code> Go compiler and tools).
|
||||||
|
Gccgo has native gdb support.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Note that
|
||||||
|
<a href="https://github.com/derekparker/delve">Delve</a> is a better
|
||||||
|
alternative to GDB when debugging Go programs built with the standard
|
||||||
|
toolchain. It understands the Go runtime, data structures, and
|
||||||
|
expressions better than GDB. Delve currently supports Linux, OSX,
|
||||||
|
and Windows on <code>amd64</code>.
|
||||||
|
For the most up-to-date list of supported platforms, please see
|
||||||
|
<a href="https://github.com/derekparker/delve/tree/master/Documentation/installation">
|
||||||
|
the Delve documentation</a>.
|
||||||
|
</p>
|
||||||
|
</i>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
GDB does not understand Go programs well.
|
GDB does not understand Go programs well.
|
||||||
The stack management, threading, and runtime contain aspects that differ
|
The stack management, threading, and runtime contain aspects that differ
|
||||||
enough from the execution model GDB expects that they can confuse
|
enough from the execution model GDB expects that they can confuse
|
||||||
the debugger, even when the program is compiled with gccgo.
|
the debugger and cause incorrect results even when the program is
|
||||||
As a consequence, although GDB can be useful in some situations, it is
|
compiled with gccgo.
|
||||||
not a reliable debugger for Go programs, particularly heavily concurrent ones.
|
As a consequence, although GDB can be useful in some situations (e.g.,
|
||||||
Moreover, it is not a priority for the Go project to address these issues, which
|
debugging Cgo code, or debugging the runtime itself), it is not
|
||||||
are difficult.
|
a reliable debugger for Go programs, particularly heavily concurrent
|
||||||
In short, the instructions below should be taken only as a guide to how
|
ones. Moreover, it is not a priority for the Go project to address
|
||||||
to use GDB when it works, not as a guarantee of success.
|
these issues, which are difficult.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
In short, the instructions below should be taken only as a guide to how
|
||||||
|
to use GDB when it works, not as a guarantee of success.
|
||||||
|
|
||||||
|
Besides this overview you might want to consult the
|
||||||
|
<a href="http://sourceware.org/gdb/current/onlinedocs/gdb/">GDB manual</a>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
In time, a more Go-centric debugging architecture may be required.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2 id="Introduction">Introduction</h2>
|
<h2 id="Introduction">Introduction</h2>
|
||||||
|
|
@ -38,16 +64,15 @@ use to inspect a live process or a core dump.
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Pass the <code>'-w'</code> flag to the linker to omit the debug information
|
Pass the <code>'-w'</code> flag to the linker to omit the debug information
|
||||||
(for example, <code>go build -ldflags "-w" prog.go</code>).
|
(for example, <code>go</code> <code>build</code> <code>-ldflags=-w</code> <code>prog.go</code>).
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The code generated by the <code>gc</code> compiler includes inlining of
|
The code generated by the <code>gc</code> compiler includes inlining of
|
||||||
function invocations and registerization of variables. These optimizations
|
function invocations and registerization of variables. These optimizations
|
||||||
can sometimes make debugging with <code>gdb</code> harder. To disable them
|
can sometimes make debugging with <code>gdb</code> harder.
|
||||||
when debugging, pass the flags <code>-gcflags "-N -l"</code> to the
|
If you find that you need to disable these optimizations,
|
||||||
<a href="/cmd/go"><code>go</code></a> command used to build the code being
|
build your program using <code>go</code> <code>build</code> <code>-gcflags=all="-N -l"</code>.
|
||||||
debugged.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -94,7 +119,7 @@ Show the name, type and location of global variables:
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
A recent extension mechanism to GDB allows it to load extension scripts for a
|
A recent extension mechanism to GDB allows it to load extension scripts for a
|
||||||
given binary. The tool chain uses this to extend GDB with a handful of
|
given binary. The toolchain uses this to extend GDB with a handful of
|
||||||
commands to inspect internals of the runtime code (such as goroutines) and to
|
commands to inspect internals of the runtime code (such as goroutines) and to
|
||||||
pretty print the built-in map, slice and channel types.
|
pretty print the built-in map, slice and channel types.
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -139,7 +164,7 @@ the DWARF code.
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
If you're interested in what the debugging information looks like, run
|
If you're interested in what the debugging information looks like, run
|
||||||
'<code>objdump -W a.out</code>' and browse through the <code>.debug_*</code>
|
<code>objdump</code> <code>-W</code> <code>a.out</code> and browse through the <code>.debug_*</code>
|
||||||
sections.
|
sections.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
@ -162,7 +187,7 @@ the form <code>pkg.(*MyType).Meth</code>.
|
||||||
<p>
|
<p>
|
||||||
In this tutorial we will inspect the binary of the
|
In this tutorial we will inspect the binary of the
|
||||||
<a href="/pkg/regexp/">regexp</a> package's unit tests. To build the binary,
|
<a href="/pkg/regexp/">regexp</a> package's unit tests. To build the binary,
|
||||||
change to <code>$GOROOT/src/regexp</code> and run <code>go test -c</code>.
|
change to <code>$GOROOT/src/regexp</code> and run <code>go</code> <code>test</code> <code>-c</code>.
|
||||||
This should produce an executable file named <code>regexp.test</code>.
|
This should produce an executable file named <code>regexp.test</code>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
@ -188,7 +213,7 @@ Loading Go Runtime support.
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The message <code>"Loading Go Runtime support"</code> means that GDB loaded the
|
The message "Loading Go Runtime support" means that GDB loaded the
|
||||||
extension from <code>$GOROOT/src/runtime/runtime-gdb.py</code>.
|
extension from <code>$GOROOT/src/runtime/runtime-gdb.py</code>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
@ -353,7 +378,7 @@ Stack level 0, frame at 0x7ffff7f9ff88:
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The command <code>info locals</code> lists all variables local to the function and their values, but is a bit
|
The command <code>info</code> <code>locals</code> lists all variables local to the function and their values, but is a bit
|
||||||
dangerous to use, since it will also try to print uninitialized variables. Uninitialized slices may cause gdb to try
|
dangerous to use, since it will also try to print uninitialized variables. Uninitialized slices may cause gdb to try
|
||||||
to print arbitrary large arrays.
|
to print arbitrary large arrays.
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -386,7 +411,7 @@ $3 = struct hchan<*testing.T>
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
That <code>struct hchan<*testing.T></code> is the
|
That <code>struct</code> <code>hchan<*testing.T></code> is the
|
||||||
runtime-internal representation of a channel. It is currently empty,
|
runtime-internal representation of a channel. It is currently empty,
|
||||||
or gdb would have pretty-printed its contents.
|
or gdb would have pretty-printed its contents.
|
||||||
</p>
|
</p>
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,36 @@ git checkout <i>release-branch</i>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Each major Go release is supported until there are two newer major releases.
|
Each major Go release is supported until there are two newer major releases.
|
||||||
For example, Go 1.8 is supported until Go 1.10 is released,
|
For example, Go 1.5 was supported until the Go 1.7 release, and Go 1.6 was
|
||||||
and Go 1.9 is supported until Go 1.11 is released.
|
supported until the Go 1.8 release.
|
||||||
We fix critical problems, including <a href="/security">critical security problems</a>,
|
We fix critical problems, including <a href="/security">critical security problems</a>,
|
||||||
in supported releases as needed by issuing minor revisions
|
in supported releases as needed by issuing minor revisions
|
||||||
(for example, Go 1.9.1, Go 1.9.2, and so on).
|
(for example, Go 1.6.1, Go 1.6.2, and so on).
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2 id="go1.10">go1.10 (released 2018/02/16)</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Go 1.10 is a major release of Go.
|
||||||
|
Read the <a href="/doc/go1.10">Go 1.10 Release Notes</a> for more information.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3 id="go1.10.minor">Minor revisions</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
go1.10.1 (released 2018/03/28) includes fixes to the compiler, runtime, and the
|
||||||
|
<code>archive/zip</code>, <code>crypto/tls</code>, <code>crypto/x509</code>,
|
||||||
|
<code>encoding/json</code>, <code>net</code>, <code>net/http</code>, and
|
||||||
|
<code>net/http/pprof</code> packages.
|
||||||
|
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.10.1">Go
|
||||||
|
1.10.1 milestone</a> on our issue tracker for details.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
go1.10.2 (released 2018/05/01) includes fixes to the compiler, linker, and go
|
||||||
|
command.
|
||||||
|
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.10.2">Go
|
||||||
|
1.10.2 milestone</a> on our issue tracker for details.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2 id="go1.9">go1.9 (released 2017/08/24)</h2>
|
<h2 id="go1.9">go1.9 (released 2017/08/24)</h2>
|
||||||
|
|
@ -49,6 +74,34 @@ See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.9.2">Go
|
||||||
1.9.2 milestone</a> on our issue tracker for details.
|
1.9.2 milestone</a> on our issue tracker for details.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
go1.9.3 (released 2018/01/22) includes fixes to the compiler, runtime,
|
||||||
|
and the <code>database/sql</code>, <code>math/big</code>, <code>net/http</code>,
|
||||||
|
and <code>net/url</code> packages.
|
||||||
|
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.9.3">Go
|
||||||
|
1.9.3 milestone</a> on our issue tracker for details.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
go1.9.4 (released 2018/02/07) includes a security fix to “go get”.
|
||||||
|
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.9.4">Go
|
||||||
|
1.9.4</a> milestone on our issue tracker for details.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
go1.9.5 (released 2018/03/28) includes fixes to the compiler, go command, and
|
||||||
|
<code>net/http/pprof</code> package.
|
||||||
|
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.9.5">Go
|
||||||
|
1.9.5 milestone</a> on our issue tracker for details.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
go1.9.6 (released 2018/05/01) includes fixes to the compiler and go command.
|
||||||
|
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.9.6">Go
|
||||||
|
1.9.6 milestone</a> on our issue tracker for details.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
<h2 id="go1.8">go1.8 (released 2017/02/16)</h2>
|
<h2 id="go1.8">go1.8 (released 2017/02/16)</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -99,6 +152,20 @@ See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.8.5">Go
|
||||||
1.8.5 milestone</a> on our issue tracker for details.
|
1.8.5 milestone</a> on our issue tracker for details.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
go1.8.6 (released 2018/01/22) includes the same fix in <code>math/big</code>
|
||||||
|
as Go 1.9.3 and was released at the same time.
|
||||||
|
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.8.6">Go
|
||||||
|
1.8.6 milestone</a> on our issue tracker for details.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
go1.8.7 (released 2018/02/07) includes a security fix to “go get”.
|
||||||
|
It contains the same fix as Go 1.9.4 and was released at the same time.
|
||||||
|
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.8.7">Go
|
||||||
|
1.8.7</a> milestone on our issue tracker for details.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h2 id="go1.7">go1.7 (released 2016/08/15)</h2>
|
<h2 id="go1.7">go1.7 (released 2016/08/15)</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,13 @@
|
||||||
"Template": true
|
"Template": true
|
||||||
}-->
|
}-->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
NOTE: In this document and others in this directory, the convention is to
|
||||||
|
set fixed-width phrases with non-fixed-width spaces, as in
|
||||||
|
<code>hello</code> <code>world</code>.
|
||||||
|
Do not send CLs removing the interior tags from such phrases.
|
||||||
|
-->
|
||||||
|
|
||||||
<h2 id="introduction">Introduction</h2>
|
<h2 id="introduction">Introduction</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -45,7 +52,7 @@ of code. The Go runtime provides <a href="https://golang.org/pkg/runtime/pprof/"
|
||||||
profiling data</a> in the format expected by the
|
profiling data</a> in the format expected by the
|
||||||
<a href="https://github.com/google/pprof/blob/master/doc/pprof.md">pprof visualization tool</a>.
|
<a href="https://github.com/google/pprof/blob/master/doc/pprof.md">pprof visualization tool</a>.
|
||||||
The profiling data can be collected during testing
|
The profiling data can be collected during testing
|
||||||
via <code>go test</code> or endpoints made available from the <a href="/pkg/net/http/pprof/">
|
via <code>go</code> <code>test</code> or endpoints made available from the <a href="/pkg/net/http/pprof/">
|
||||||
net/http/pprof</a> package. Users need to collect the profiling data and use pprof tools to filter
|
net/http/pprof</a> package. Users need to collect the profiling data and use pprof tools to filter
|
||||||
and visualize the top code paths.
|
and visualize the top code paths.
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -119,7 +126,7 @@ so it is recommended to collect only a single profile at a time.
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The Go tools provide text, graph, and <a href="http://valgrind.org/docs/manual/cl-manual.html">callgrind</a>
|
The Go tools provide text, graph, and <a href="http://valgrind.org/docs/manual/cl-manual.html">callgrind</a>
|
||||||
visualization of the profile data via
|
visualization of the profile data using
|
||||||
<code><a href="https://github.com/google/pprof/blob/master/doc/pprof.md">go tool pprof</a></code>.
|
<code><a href="https://github.com/google/pprof/blob/master/doc/pprof.md">go tool pprof</a></code>.
|
||||||
Read <a href="https://blog.golang.org/profiling-go-programs">Profiling Go programs</a>
|
Read <a href="https://blog.golang.org/profiling-go-programs">Profiling Go programs</a>
|
||||||
to see them in action.
|
to see them in action.
|
||||||
|
|
@ -149,9 +156,11 @@ in the listing.</p>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Another way to visualize profile data is a <a href="https://github.com/uber/go-torch">flame graph</a>.
|
Another way to visualize profile data is a <a href="http://www.brendangregg.com/flamegraphs.html">flame graph</a>.
|
||||||
Flame graphs allow you to move in a specific ancestry path, so you can zoom
|
Flame graphs allow you to move in a specific ancestry path, so you can zoom
|
||||||
in/out specific sections of code more easily.
|
in/out of specific sections of code.
|
||||||
|
The <a href="https://github.com/google/pprof">upstream pprof</a>
|
||||||
|
has support for flame graphs.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -183,9 +192,19 @@ handler on :7777 at /custom_debug_path/profile:
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<pre>
|
<pre>
|
||||||
mux := http.NewServeMux()
|
package main
|
||||||
mux.HandleFunc("/custom_debug_path/profile", pprof.Profile)
|
|
||||||
http.ListenAndServe(":7777", mux)
|
import (
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"net/http/pprof"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
mux := http.NewServeMux()
|
||||||
|
mux.HandleFunc("/custom_debug_path/profile", pprof.Profile)
|
||||||
|
log.Fatal(http.ListenAndServe(":7777", mux))
|
||||||
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
@ -203,7 +222,7 @@ an execution tracer to trace the runtime events within an interval.
|
||||||
<p>Tracing enables us to:</p>
|
<p>Tracing enables us to:</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>Instrument and profile application latency in a Go process.</li>
|
<li>Instrument and analyze application latency in a Go process.</li>
|
||||||
<li>Measure the cost of specific calls in a long chain of calls.</li>
|
<li>Measure the cost of specific calls in a long chain of calls.</li>
|
||||||
<li>Figure out the utilization and performance improvements.
|
<li>Figure out the utilization and performance improvements.
|
||||||
Bottlenecks are not always obvious without tracing data.</li>
|
Bottlenecks are not always obvious without tracing data.</li>
|
||||||
|
|
@ -252,7 +271,8 @@ trace spans. You need to manually instrument your code to create, end, and annot
|
||||||
<p><strong>How should I propagate trace headers in Go libraries?</strong></p>
|
<p><strong>How should I propagate trace headers in Go libraries?</strong></p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
You can propagate trace identifiers and tags in the <code>context.Context</code>.
|
You can propagate trace identifiers and tags in the
|
||||||
|
<a href="/pkg/context#Context"><code>context.Context</code></a>.
|
||||||
There is no canonical trace key or common representation of trace headers
|
There is no canonical trace key or common representation of trace headers
|
||||||
in the industry yet. Each tracing provider is responsible for providing propagation
|
in the industry yet. Each tracing provider is responsible for providing propagation
|
||||||
utilities in their Go libraries.
|
utilities in their Go libraries.
|
||||||
|
|
@ -265,7 +285,8 @@ runtime can be included in a trace?</strong>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The standard library and runtime are trying to expose several additional APIs
|
The standard library and runtime are trying to expose several additional APIs
|
||||||
to notify on low level internal events. For example, httptrace.ClientTrace
|
to notify on low level internal events. For example,
|
||||||
|
<a href="/pkg/net/http/httptrace#ClientTrace"><code>httptrace.ClientTrace</code></a>
|
||||||
provides APIs to follow low-level events in the life cycle of an outgoing request.
|
provides APIs to follow low-level events in the life cycle of an outgoing request.
|
||||||
There is an ongoing effort to retrieve low-level runtime events from
|
There is an ongoing effort to retrieve low-level runtime events from
|
||||||
the runtime execution tracer and allow users to define and record their user events.
|
the runtime execution tracer and allow users to define and record their user events.
|
||||||
|
|
@ -303,25 +324,25 @@ create confusion.
|
||||||
<p><strong>How well do debuggers work with Go programs?</strong></p>
|
<p><strong>How well do debuggers work with Go programs?</strong></p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
As of Go 1.9, the DWARF info generated by the gc compiler is not complete
|
The <code>gc</code> compiler performs optimizations such as
|
||||||
and sometimes makes debugging harder. There is an ongoing effort to improve the
|
function inlining and variable registerization. These optimizations
|
||||||
DWARF information to help the debuggers display more accurate information.
|
sometimes make debugging with debuggers harder. There is an ongoing
|
||||||
Until those improvements are in you may prefer to disable compiler
|
effort to improve the quality of the DWARF information generated for
|
||||||
optimizations during development for more accuracy. To disable optimizations,
|
optimized binaries. Until those improvements are available, we recommend
|
||||||
use the "-N -l" compiler flags. For example, the following command builds
|
disabling optimizations when building the code being debugged. The following
|
||||||
a package with no compiler optimizations:
|
command builds a package with no compiler optimizations:
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<pre>
|
<pre>
|
||||||
$ go build -gcflags="-N -l"
|
$ go build -gcflags=all="-N -l"
|
||||||
</pre>
|
</pre>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
As part of the improvement effort, Go 1.10 introduced a new compiler
|
||||||
As of Go 1.10, the Go binaries will have the required DWARF information
|
flag <code>-dwarflocationlists</code>. The flag causes the compiler to
|
||||||
for accurate debugging. To enable the DWARF improvements, use the following
|
add location lists that helps debuggers work with optimized binaries.
|
||||||
compiler flags and use GDB until Delve supports location lists:
|
The following command builds a package with optimizations but with
|
||||||
</p>
|
the DWARF location lists:
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<pre>
|
<pre>
|
||||||
|
|
@ -333,9 +354,7 @@ $ go build -gcflags="-dwarflocationlists=true"
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Even though both delve and gdb provides CLIs, most editor integrations
|
Even though both delve and gdb provides CLIs, most editor integrations
|
||||||
and IDEs provides debugging-specific user interfaces. Please refer to
|
and IDEs provides debugging-specific user interfaces.
|
||||||
the <a href="/doc/editors.html">editors guide</a> to see the options
|
|
||||||
with debugger UI support.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p><strong>Is it possible to do postmortem debugging with Go programs?</strong></p>
|
<p><strong>Is it possible to do postmortem debugging with Go programs?</strong></p>
|
||||||
|
|
@ -421,7 +440,7 @@ Use profiling tools instead first to address them.</p>
|
||||||
fine, and then it became serialized. It suggests that there might
|
fine, and then it became serialized. It suggests that there might
|
||||||
be lock contention for a shared resource that creates a bottleneck.</p>
|
be lock contention for a shared resource that creates a bottleneck.</p>
|
||||||
|
|
||||||
<p>See <a href="https://golang.org/cmd/trace/"><code>go tool trace</code></a>
|
<p>See <a href="https://golang.org/cmd/trace/"><code>go</code> <code>tool</code> <code>trace</code></a>
|
||||||
to collect and analyze runtime traces.
|
to collect and analyze runtime traces.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
|
||||||
196
doc/editors.html
196
doc/editors.html
|
|
@ -33,199 +33,3 @@ community-maintained list of
|
||||||
<a href="https://github.com/golang/go/wiki/IDEsAndTextEditorPlugins">IDEs and text editor plugins</a>
|
<a href="https://github.com/golang/go/wiki/IDEsAndTextEditorPlugins">IDEs and text editor plugins</a>
|
||||||
is available at the Wiki.
|
is available at the Wiki.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
|
||||||
Each development environment integrates a number of Go-specific tools.
|
|
||||||
The following feature matrix lists and compares the most significant features.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<table class="features-matrix">
|
|
||||||
<tr>
|
|
||||||
<th></th>
|
|
||||||
<th><img title="Vim Go" src="/doc/editors/vimgo.png"><br>vim</th>
|
|
||||||
<th><img title="Visual Studio Code" src="/doc/editors/vscodego.png"><br>Visual Studio Code</th>
|
|
||||||
<th><img title="GoLand" src="/doc/editors/goland.png"><br>GoLand</th>
|
|
||||||
<th><img title="Go-Plus" src="/doc/editors/go-plus.png"><br>Atom</th>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="feature-row" colspan="5">Editing features</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Build and run from the editor/IDE</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Autocompletion of identifiers (variable, method, and function names)</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Type-aware autocompletion</td>
|
|
||||||
<td class="no">No</td>
|
|
||||||
<td class="no">No</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
<td class="no">No</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Rename identifiers</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Auto format, build, vet, and lint on save</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
<td class="yes">Yes<sup>1</sup></td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Auto insert import paths and remove unused on save</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
<td class="yes">Yes<sup>2</sup></td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Auto generate JSON, XML tags for struct fields</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="feature-row" colspan="5">Navigation features</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Display documentation inline, or open godoc in browser</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Switch between <code>*.go</code> and <code>*_test.go</code> file</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
<td class="yes">No</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Jump to definition and referees</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Look up for interface implementations</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Search for callers and callees</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="feature-row" colspan="5">Testing and debugging features</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Debugger support</td>
|
|
||||||
<td class="no">No</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
<td class="yes">Yes<sup>3</sup></td>
|
|
||||||
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Run a single test case, all tests from file, or all tests from a package</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
<td class="no">No</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Auto generate tests for packages, files and identifiers</td>
|
|
||||||
<td class="no">No</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
<td class="no">No</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Debug tests</td>
|
|
||||||
<td class="no">No</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
<td class="yes">Yes<sup>3</sup></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Display test coverage</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
<td class="yes">Yes</td>
|
|
||||||
</tr>
|
|
||||||
<tr class="download">
|
|
||||||
<td></td>
|
|
||||||
<td><a href="https://github.com/fatih/vim-go">Install</a></td>
|
|
||||||
<td><a href="https://marketplace.visualstudio.com/items?itemName=lukehoban.Go">Install</a></td>
|
|
||||||
<td><a href="https://www.jetbrains.com/go">Install</a></td>
|
|
||||||
<td><a href="https://atom.io/packages/go-plus">Install</a></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<sup>1</sup>Possible when enabled via Settings > Go > On Save, <code>go</code> <code>vet</code> and <code>golint</code> are available via plugins. Also runs tests on save if configured.
|
|
||||||
<br>
|
|
||||||
<sup>2</sup>Additionally, user input can disambiguate when two or more options are available.
|
|
||||||
<br>
|
|
||||||
<sup>3</sup>Available if the <a href="https://atom.io/packages/go-debug">go-debug</a> package is installed.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.features-matrix {
|
|
||||||
min-width: 800px;
|
|
||||||
border-collapse: collapse;
|
|
||||||
}
|
|
||||||
.features-matrix th {
|
|
||||||
width: 60px;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 14px;
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
.features-matrix th img {
|
|
||||||
width: 48px;
|
|
||||||
}
|
|
||||||
.features-matrix .yes {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.features-matrix .no {
|
|
||||||
text-align: center;
|
|
||||||
background-color: #ffe9e9;
|
|
||||||
}
|
|
||||||
.features-matrix .download {
|
|
||||||
font-weight: bold;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.features-matrix td {
|
|
||||||
padding: 11px 5px 11px 5px;
|
|
||||||
border-bottom: solid 1px #ebebeb;
|
|
||||||
}
|
|
||||||
.features-matrix .feature-row {
|
|
||||||
background-color: #ebebeb;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 15 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 9.2 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 7.4 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 3.3 KiB |
|
|
@ -3588,8 +3588,7 @@ That's left as an exercise for the reader.
|
||||||
<p>
|
<p>
|
||||||
Let's finish with a complete Go program, a web server.
|
Let's finish with a complete Go program, a web server.
|
||||||
This one is actually a kind of web re-server.
|
This one is actually a kind of web re-server.
|
||||||
Google provides a service at
|
Google provides a service at <code>chart.apis.google.com</code>
|
||||||
<a href="http://chart.apis.google.com">http://chart.apis.google.com</a>
|
|
||||||
that does automatic formatting of data into charts and graphs.
|
that does automatic formatting of data into charts and graphs.
|
||||||
It's hard to use interactively, though,
|
It's hard to use interactively, though,
|
||||||
because you need to put the data into the URL as a query.
|
because you need to put the data into the URL as a query.
|
||||||
|
|
|
||||||
|
|
@ -166,7 +166,7 @@ providing a complete Go 1.1 implementation.
|
||||||
<h3 id="gc_flag">Command-line flag parsing</h3>
|
<h3 id="gc_flag">Command-line flag parsing</h3>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
In the gc tool chain, the compilers and linkers now use the
|
In the gc toolchain, the compilers and linkers now use the
|
||||||
same command-line flag parsing rules as the Go flag package, a departure
|
same command-line flag parsing rules as the Go flag package, a departure
|
||||||
from the traditional Unix flag parsing. This may affect scripts that invoke
|
from the traditional Unix flag parsing. This may affect scripts that invoke
|
||||||
the tool directly.
|
the tool directly.
|
||||||
|
|
@ -305,7 +305,7 @@ The race detector is documented in <a href="/doc/articles/race_detector.html">a
|
||||||
<p>
|
<p>
|
||||||
Due to the change of the <a href="#int"><code>int</code></a> to 64 bits and
|
Due to the change of the <a href="#int"><code>int</code></a> to 64 bits and
|
||||||
a new internal <a href="//golang.org/s/go11func">representation of functions</a>,
|
a new internal <a href="//golang.org/s/go11func">representation of functions</a>,
|
||||||
the arrangement of function arguments on the stack has changed in the gc tool chain.
|
the arrangement of function arguments on the stack has changed in the gc toolchain.
|
||||||
Functions written in assembly will need to be revised at least
|
Functions written in assembly will need to be revised at least
|
||||||
to adjust frame pointer offsets.
|
to adjust frame pointer offsets.
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -395,7 +395,7 @@ Run <code>go help test</code> for more information.
|
||||||
The <a href="/cmd/fix/"><code>fix</code></a> command, usually run as
|
The <a href="/cmd/fix/"><code>fix</code></a> command, usually run as
|
||||||
<code>go fix</code>, no longer applies fixes to update code from
|
<code>go fix</code>, no longer applies fixes to update code from
|
||||||
before Go 1 to use Go 1 APIs.
|
before Go 1 to use Go 1 APIs.
|
||||||
To update pre-Go 1 code to Go 1.1, use a Go 1.0 tool chain
|
To update pre-Go 1 code to Go 1.1, use a Go 1.0 toolchain
|
||||||
to convert the code to Go 1.0 first.
|
to convert the code to Go 1.0 first.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
@ -427,7 +427,7 @@ To build a file only with Go 1.0.x, use the converse constraint:
|
||||||
<h3 id="platforms">Additional platforms</h3>
|
<h3 id="platforms">Additional platforms</h3>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The Go 1.1 tool chain adds experimental support for <code>freebsd/arm</code>,
|
The Go 1.1 toolchain adds experimental support for <code>freebsd/arm</code>,
|
||||||
<code>netbsd/386</code>, <code>netbsd/amd64</code>, <code>netbsd/arm</code>,
|
<code>netbsd/386</code>, <code>netbsd/amd64</code>, <code>netbsd/arm</code>,
|
||||||
<code>openbsd/386</code> and <code>openbsd/amd64</code> platforms.
|
<code>openbsd/386</code> and <code>openbsd/amd64</code> platforms.
|
||||||
</p>
|
</p>
|
||||||
|
|
|
||||||
244
doc/go1.10.html
244
doc/go1.10.html
|
|
@ -15,34 +15,37 @@ Do not send CLs removing the interior tags from such phrases.
|
||||||
ul li { margin: 0.5em 0; }
|
ul li { margin: 0.5em 0; }
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<h2 id="introduction">DRAFT RELEASE NOTES - Introduction to Go 1.10</h2>
|
<h2 id="introduction">Introduction to Go 1.10</h2>
|
||||||
|
|
||||||
<p><strong>
|
|
||||||
Go 1.10 is not yet released. These are work-in-progress
|
|
||||||
release notes. Go 1.10 is expected to be released in February 2018.
|
|
||||||
</strong></p>
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The latest Go release, version 1.10, arrives six months after <a href="go1.9">go1.9</a>.
|
The latest Go release, version 1.10, arrives six months after <a href="go1.9">Go 1.9</a>.
|
||||||
Most of its changes are in the implementation of the toolchain, runtime, and libraries.
|
Most of its changes are in the implementation of the toolchain, runtime, and libraries.
|
||||||
As always, the release maintains the Go 1 <a href="/doc/go1compat.html">promise of compatibility</a>.
|
As always, the release maintains the Go 1 <a href="/doc/go1compat.html">promise of compatibility</a>.
|
||||||
We expect almost all Go programs to continue to compile and run as before.
|
We expect almost all Go programs to continue to compile and run as before.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
OVERVIEW HERE
|
This release improves <a href="#build">caching of built packages</a>,
|
||||||
|
adds <a href="#test">caching of successful test results</a>,
|
||||||
|
runs <a href="#test-vet">vet automatically during tests</a>,
|
||||||
|
and
|
||||||
|
permits <a href="#cgo">passing string values directly between Go and C using cgo</a>.
|
||||||
|
A new <a href="#cgo">compiler option whitelist</a> may cause
|
||||||
|
unexpected <a href="https://golang.org/s/invalidflag"><code>invalid
|
||||||
|
flag</code></a> errors in code that built successfully with older
|
||||||
|
releases.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2 id="language">Changes to the language</h2>
|
<h2 id="language">Changes to the language</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
There are no substantive changes to the language.
|
There are no significant changes to the language specification.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p><!-- CL 60230 -->
|
<p><!-- CL 60230 -->
|
||||||
A corner case involving shifts by untyped constants has been clarified,
|
A corner case involving shifts of untyped constants has been clarified,
|
||||||
and as a result the compilers have been updated to allow the index expression
|
and as a result the compilers have been updated to allow the index expression
|
||||||
<code>x[1.0</code> <code><<</code> <code>s]</code> where <code>s</code> is an untyped constant;
|
<code>x[1.0</code> <code><<</code> <code>s]</code> where <code>s</code> is an unsigned integer;
|
||||||
the <a href="/pkg/go/types/">go/types</a> package already did.
|
the <a href="/pkg/go/types/">go/types</a> package already did.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
@ -64,11 +67,6 @@ in particular <a href="#asm">new instructions in the assembler</a>
|
||||||
and improvements to the code generated by the compilers.
|
and improvements to the code generated by the compilers.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p id="darwin">
|
|
||||||
Go 1.10 is the last release that will run on OS X 10.8 Mountain Lion.
|
|
||||||
Go 1.11 will require OS X 10.9 Mavericks or later.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p id="freebsd">
|
<p id="freebsd">
|
||||||
As <a href="go1.9#freebsd">announced in the Go 1.9 release notes</a>,
|
As <a href="go1.9#freebsd">announced in the Go 1.9 release notes</a>,
|
||||||
Go 1.10 now requires FreeBSD 10.3 or later;
|
Go 1.10 now requires FreeBSD 10.3 or later;
|
||||||
|
|
@ -76,15 +74,9 @@ support for FreeBSD 9.3 has been removed.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p id="netbsd">
|
<p id="netbsd">
|
||||||
Go now runs on NetBSD again, but requires the unreleased NetBSD 8.
|
Go now runs on NetBSD again but requires the unreleased NetBSD 8.
|
||||||
Only <code>GOARCH=amd64</code> running on NetBSD amd64 and <code>GOARCH=386</code>
|
Only <code>GOARCH</code> <code>amd64</code> and <code>386</code> have
|
||||||
running on NetBSD i386 are known to work. 64-bit Go binaries are known to
|
been fixed. The <code>arm</code> port is still broken.
|
||||||
fail on 32-bit NetBSD kernels. <code>GOARCH=arm</code> is untested.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p id="openbsd">
|
|
||||||
Go 1.10 is the last release that will run on OpenBSD 6.0.
|
|
||||||
Go 1.11 will require OpenBSD 6.2.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p id="mips">
|
<p id="mips">
|
||||||
|
|
@ -94,13 +86,34 @@ On 32-bit MIPS systems, the new environment variable settings
|
||||||
hardware instructions or software emulation for floating-point computations.
|
hardware instructions or software emulation for floating-point computations.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<p id="openbsd">
|
||||||
|
Go 1.10 is the last release that will run on OpenBSD 6.0.
|
||||||
|
Go 1.11 will require OpenBSD 6.2.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p id="darwin">
|
||||||
|
Go 1.10 is the last release that will run on OS X 10.8 Mountain Lion or OS X 10.9 Mavericks.
|
||||||
|
Go 1.11 will require OS X 10.10 Yosemite or later.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p id="windows">
|
||||||
|
Go 1.10 is the last release that will run on Windows XP or Windows Vista.
|
||||||
|
Go 1.11 will require Windows 7 or later.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h2 id="tools">Tools</h2>
|
<h2 id="tools">Tools</h2>
|
||||||
|
|
||||||
<h3 id="goroot">Default GOROOT & GOTMPDIR</h3>
|
<h3 id="goroot">Default GOROOT & GOTMPDIR</h3>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
TODO: default GOROOT changes in cmd/go
|
If the environment variable <code>$GOROOT</code> is unset,
|
||||||
TODO: computed GOROOT change
|
the go tool previously used the default <code>GOROOT</code>
|
||||||
|
set during toolchain compilation.
|
||||||
|
Now, before falling back to that default, the go tool attempts to
|
||||||
|
deduce <code>GOROOT</code> from its own executable path.
|
||||||
|
This allows binary distributions to be unpacked anywhere in the
|
||||||
|
file system and then be used without setting <code>GOROOT</code>
|
||||||
|
explicitly.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -146,11 +159,11 @@ back and forth between different branches in a version control system).
|
||||||
The old advice to add the <code>-i</code> flag for speed, as in <code>go</code> <code>build</code> <code>-i</code>
|
The old advice to add the <code>-i</code> flag for speed, as in <code>go</code> <code>build</code> <code>-i</code>
|
||||||
or <code>go</code> <code>test</code> <code>-i</code>,
|
or <code>go</code> <code>test</code> <code>-i</code>,
|
||||||
is no longer necessary: builds run just as fast without <code>-i</code>.
|
is no longer necessary: builds run just as fast without <code>-i</code>.
|
||||||
For more details, see <a href="TODO"><code>go</code> <code>help</code> <code>cache</code></a>.
|
For more details, see <a href="/cmd/go/#hdr-Build_and_test_caching"><code>go</code> <code>help</code> <code>cache</code></a>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The <code>go</code> </code>install</code> command now installs only the
|
The <code>go</code> <code>install</code> command now installs only the
|
||||||
packages and commands listed directly on the command line.
|
packages and commands listed directly on the command line.
|
||||||
For example, <code>go</code> <code>install</code> <code>cmd/gofmt</code>
|
For example, <code>go</code> <code>install</code> <code>cmd/gofmt</code>
|
||||||
installs the gofmt program but not any of the packages on which it depends.
|
installs the gofmt program but not any of the packages on which it depends.
|
||||||
|
|
@ -188,7 +201,7 @@ only to command lines using a subset of the
|
||||||
The idiomatic way to bypass test caching is to use <code>-count=1</code>.
|
The idiomatic way to bypass test caching is to use <code>-count=1</code>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p id="test-vet">
|
||||||
The <code>go</code> <code>test</code> command now automatically runs
|
The <code>go</code> <code>test</code> command now automatically runs
|
||||||
<code>go</code> <code>vet</code> on the package being tested,
|
<code>go</code> <code>vet</code> on the package being tested,
|
||||||
to identify significant problems before running the test.
|
to identify significant problems before running the test.
|
||||||
|
|
@ -253,7 +266,19 @@ and the <a href="/cmd/test2json/">test2json documentation</a>.
|
||||||
<h3 id="cgo">Cgo</h3>
|
<h3 id="cgo">Cgo</h3>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Cgo now implements a C typedef like “<code>typedef</code> <code>X</code> <code>Y</code>;” using a Go type alias,
|
Options specified by cgo using <code>#cgo CFLAGS</code> and the like
|
||||||
|
are now checked against a whitelist of permitted options.
|
||||||
|
This closes a security hole in which a downloaded package uses
|
||||||
|
compiler options like
|
||||||
|
<span style="white-space: nowrap"><code>-fplugin</code></span>
|
||||||
|
to run arbitrary code on the machine where it is being built.
|
||||||
|
This can cause a build error such as <code>invalid flag in #cgo CFLAGS</code>.
|
||||||
|
For more background, and how to handle this error, see
|
||||||
|
<a href="https://golang.org/s/invalidflag">https://golang.org/s/invalidflag</a>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Cgo now implements a C typedef like “<code>typedef</code> <code>X</code> <code>Y</code>” using a Go type alias,
|
||||||
so that Go code may use the types <code>C.X</code> and <code>C.Y</code> interchangeably.
|
so that Go code may use the types <code>C.X</code> and <code>C.Y</code> interchangeably.
|
||||||
It also now supports the use of niladic function-like macros.
|
It also now supports the use of niladic function-like macros.
|
||||||
Also, the documentation has been updated to clarify that
|
Also, the documentation has been updated to clarify that
|
||||||
|
|
@ -261,9 +286,13 @@ Go structs and Go arrays are not supported in the type signatures of cgo-exporte
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
TODO: CL 70890 "permit passing string values directly between Go and C."
|
Cgo now supports direct access to Go string values from C.
|
||||||
<br>
|
Functions in the C preamble may use the type <code>_GoString_</code>
|
||||||
TODO: CL 66332 "special case C ptr types to use uintptr."
|
to accept a Go string as an argument.
|
||||||
|
C code may call <code>_GoStringLen</code> and <code>_GoStringPtr</code>
|
||||||
|
for direct access to the contents of the string.
|
||||||
|
A value of type <code>_GoString_</code>
|
||||||
|
may be passed in a call to an exported Go function that takes an argument of Go type <code>string</code>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -275,10 +304,37 @@ The new set of environment variables <code>CC_FOR_<i>goos</i>_<i>goarch</i></cod
|
||||||
allows specifying a different default C compiler for each target.
|
allows specifying a different default C compiler for each target.
|
||||||
Note that these variables only apply during toolchain bootstrap,
|
Note that these variables only apply during toolchain bootstrap,
|
||||||
to set the defaults used by the resulting toolchain.
|
to set the defaults used by the resulting toolchain.
|
||||||
Later <code>go</code> <code>build</code> commands refer to the <code>CC</code> environment
|
Later <code>go</code> <code>build</code> commands use the <code>CC</code> environment
|
||||||
variable or else the built-in default.
|
variable or else the built-in default.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Cgo now translates some C types that would normally map to a pointer
|
||||||
|
type in Go, to a <code>uintptr</code> instead. These types include
|
||||||
|
the <code>CFTypeRef</code> hierarchy in Darwin's CoreFoundation
|
||||||
|
framework and the <code>jobject</code> hierarchy in Java's JNI
|
||||||
|
interface.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
These types must be <code>uintptr</code> on the Go side because they
|
||||||
|
would otherwise confuse the Go garbage collector; they are sometimes
|
||||||
|
not really pointers but data structures encoded in a pointer-sized integer.
|
||||||
|
Pointers to Go memory must not be stored in these <code>uintptr</code> values.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Because of this change, values of the affected types need to be
|
||||||
|
zero-initialized with the constant <code>0</code> instead of the
|
||||||
|
constant <code>nil</code>. Go 1.10 provides <code>gofix</code>
|
||||||
|
modules to help with that rewrite:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
go tool fix -r cftype <pkg>
|
||||||
|
go tool fix -r jni <pkg>
|
||||||
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
For more details, see the <a href="/cmd/cgo/">cgo documentation</a>.
|
For more details, see the <a href="/cmd/cgo/">cgo documentation</a>.
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -336,8 +392,9 @@ without the binary that produced the profile.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The <a href="/cmd/pprof/"><code>go</code> <code>tool</code> <code>pprof</code></a> profile visualizer has been updated to
|
The <a href="/cmd/pprof/"><code>go</code> <code>tool</code> <code>pprof</code></a>
|
||||||
the latest version from <a href="https://github.com/google/pprof">github.com/google/pprof</a>,
|
profile visualizer has been updated to git version 9e20b5b (2017-11-08)
|
||||||
|
from <a href="https://github.com/google/pprof">github.com/google/pprof</a>,
|
||||||
which includes an updated web interface.
|
which includes an updated web interface.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
@ -383,17 +440,10 @@ a repository is not “properly formatted” is inherently fragile and not recom
|
||||||
<p>
|
<p>
|
||||||
If multiple programs must agree about which version of gofmt is used to format a source file,
|
If multiple programs must agree about which version of gofmt is used to format a source file,
|
||||||
we recommend that they do this by arranging to invoke the same gofmt binary.
|
we recommend that they do this by arranging to invoke the same gofmt binary.
|
||||||
For example, in the Go open source repository, we arrange for goimports and
|
For example, in the Go open source repository, our Git pre-commit hook is written in Go
|
||||||
our Git pre-commit hook to agree about source code formatting by having both
|
and could import <code>go/format</code> directly, but instead it invokes the <code>gofmt</code>
|
||||||
invoke the gofmt binary found in the current path.
|
binary found in the current path, so that the pre-commit hook need not be recompiled
|
||||||
TODO: Make goimports actually do that. #22695.
|
each time <code>gofmt</code> changes.
|
||||||
As another example, inside Google we arrange that source code presubmit
|
|
||||||
checks run a gofmt binary maintained at a fixed path in a shared, distributed file system;
|
|
||||||
that on engineering workstations <code>/usr/bin/gofmt</code>
|
|
||||||
is a symbolic link to that same path;
|
|
||||||
and that all editor integrations used for Google development
|
|
||||||
explicitly invoke /usr/bin/gofmt.
|
|
||||||
TODO: TMI?
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h3 id="compiler">Compiler Toolchain</h3>
|
<h3 id="compiler">Compiler Toolchain</h3>
|
||||||
|
|
@ -412,10 +462,10 @@ and each package is now presented as its own DWARF compilation unit.
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The various <a href="https://docs.google.com/document/d/1nr-TQHw_er6GOQRsF6T43GGhFDelrAP0NqSS_00RgZQ/edit">build modes</a>
|
The various <a href="https://docs.google.com/document/d/1nr-TQHw_er6GOQRsF6T43GGhFDelrAP0NqSS_00RgZQ/edit">build modes</a>
|
||||||
has been ported to more systems.
|
have been ported to more systems.
|
||||||
Specifically, <code>c-shared</code> now works on <code>linux/ppc64le</code>, <code>windows/386</code>, and <code>windows/amd64</code>;
|
Specifically, <code>c-shared</code> now works on <code>linux/ppc64le</code>, <code>windows/386</code>, and <code>windows/amd64</code>;
|
||||||
<code>pie</code> now works on <code>darwin/amd64</code> and also forces the use of external linking on all systems;
|
<code>pie</code> now works on <code>darwin/amd64</code> and also forces the use of external linking on all systems;
|
||||||
and <code>plugin</code> now works on <code>linux/ppc64le</code>.
|
and <code>plugin</code> now works on <code>linux/ppc64le</code> and <code>darwin/amd64</code>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -517,7 +567,11 @@ to avoid clearing the condition flags unexpectedly.
|
||||||
<h3 id="gccgo">Gccgo</h3>
|
<h3 id="gccgo">Gccgo</h3>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
TODO: Words about GCC 8 and Go 1.10.
|
Due to the alignment of Go's semiannual release schedule with GCC's
|
||||||
|
annual release schedule,
|
||||||
|
GCC release 7 contains the Go 1.8.3 version of gccgo.
|
||||||
|
We expect that the next release, GCC 8, will contain the Go 1.10
|
||||||
|
version of gccgo.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2 id="runtime">Runtime</h2>
|
<h2 id="runtime">Runtime</h2>
|
||||||
|
|
@ -537,7 +591,7 @@ Now, the calls nest: if <code>LockOSThread</code> is called multiple times,
|
||||||
in order to unlock the thread.
|
in order to unlock the thread.
|
||||||
Existing code that was careful not to nest these calls will remain correct.
|
Existing code that was careful not to nest these calls will remain correct.
|
||||||
Existing code that incorrectly assumed the calls nested will become correct.
|
Existing code that incorrectly assumed the calls nested will become correct.
|
||||||
Most uses of these functions in public Go source falls into the second category.
|
Most uses of these functions in public Go source code falls into the second category.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -555,12 +609,23 @@ optimization decisions and implementation details.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
There is no longer a limit on the <a href="/pkg/runtime/#GOMAXPROCS"><code>GOMAXPROCS</code></a> setting.
|
The garbage collector has been modified to reduce its impact on allocation latency.
|
||||||
(In Go 1.9 the limit was 1024.)
|
It now uses a smaller fraction of the overall CPU when running, but it may run more of the time.
|
||||||
|
The total CPU consumed by the garbage collector has not changed significantly.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
TODO: Anything about CL 59970: "runtime: separate soft and hard heap limits"?
|
The <a href="/pkg/runtime/#GOROOT"><code>GOROOT</code></a> function
|
||||||
|
now defaults (when the <code>$GOROOT</code> environment variable is not set)
|
||||||
|
to the <code>GOROOT</code> or <code>GOROOT_FINAL</code> in effect
|
||||||
|
at the time the calling program was compiled.
|
||||||
|
Previously it used the <code>GOROOT</code> or <code>GOROOT_FINAL</code> in effect
|
||||||
|
at the time the toolchain that compiled the calling program was compiled.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
There is no longer a limit on the <a href="/pkg/runtime/#GOMAXPROCS"><code>GOMAXPROCS</code></a> setting.
|
||||||
|
(In Go 1.9 the limit was 1024.)
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2 id="performance">Performance</h2>
|
<h2 id="performance">Performance</h2>
|
||||||
|
|
@ -689,9 +754,9 @@ The
|
||||||
<a href="/pkg/bytes/#Split"><code>Split</code></a>,
|
<a href="/pkg/bytes/#Split"><code>Split</code></a>,
|
||||||
and
|
and
|
||||||
<a href="/pkg/bytes/#SplitAfter"><code>SplitAfter</code></a>
|
<a href="/pkg/bytes/#SplitAfter"><code>SplitAfter</code></a>
|
||||||
each already returned slices pointing into the same underlying array as its input.
|
functions have always returned subslices of their inputs.
|
||||||
Go 1.10 changes each of the returned subslices to have capacity equal to its length,
|
Go 1.10 changes each returned subslice to have capacity equal to its length,
|
||||||
so that appending to a subslice will not overwrite adjacent data in the original input.
|
so that appending to one cannot overwrite adjacent data in the original input.
|
||||||
</p>
|
</p>
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
|
|
@ -717,13 +782,13 @@ them unless explicitly advertised.
|
||||||
<dl id="crypto/x509"><dt><a href="/pkg/crypto/x509/">crypto/x509</a></dt>
|
<dl id="crypto/x509"><dt><a href="/pkg/crypto/x509/">crypto/x509</a></dt>
|
||||||
<dd>
|
<dd>
|
||||||
<p>
|
<p>
|
||||||
Leaf certificate validation now enforces the name constraints for all
|
<a href="/pkg/crypto/x509/#Certificate.Verify"><code>Certificate.Verify</code></a>
|
||||||
|
now enforces the name constraints for all
|
||||||
names contained in the certificate, not just the one name that a client has asked about.
|
names contained in the certificate, not just the one name that a client has asked about.
|
||||||
Extended key usage restrictions are similarly now checked all at once.
|
Extended key usage restrictions are similarly now checked all at once.
|
||||||
As a result, after a certificate has been validated, now it can be trusted in its entirety.
|
As a result, after a certificate has been validated, now it can be trusted in its entirety.
|
||||||
It is no longer necessary to revalidate the certificate for each additional name
|
It is no longer necessary to revalidate the certificate for each additional name
|
||||||
or key usage.
|
or key usage.
|
||||||
TODO: Link to docs that may not exist yet.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -731,7 +796,8 @@ Parsed certificates also now report URI names and IP, email, and URI constraints
|
||||||
<a href="/pkg/crypto/x509/#Certificate"><code>Certificate</code></a> fields
|
<a href="/pkg/crypto/x509/#Certificate"><code>Certificate</code></a> fields
|
||||||
<code>URIs</code>, <code>PermittedIPRanges</code>, <code>ExcludedIPRanges</code>,
|
<code>URIs</code>, <code>PermittedIPRanges</code>, <code>ExcludedIPRanges</code>,
|
||||||
<code>PermittedEmailAddresses</code>, <code>ExcludedEmailAddresses</code>,
|
<code>PermittedEmailAddresses</code>, <code>ExcludedEmailAddresses</code>,
|
||||||
<code>PermittedURIDomains</code>, and <code>ExcludedURIDomains</code>.
|
<code>PermittedURIDomains</code>, and <code>ExcludedURIDomains</code>. Certificates with
|
||||||
|
invalid values for those fields are now rejected.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -760,6 +826,13 @@ formats the X.509 distinguished name in the standard RFC 2253 format.
|
||||||
<dl id="database/sql/driver"><dt><a href="/pkg/database/sql/driver/">database/sql/driver</a></dt>
|
<dl id="database/sql/driver"><dt><a href="/pkg/database/sql/driver/">database/sql/driver</a></dt>
|
||||||
<dd>
|
<dd>
|
||||||
<p>
|
<p>
|
||||||
|
Drivers that currently hold on to the destination buffer provided by
|
||||||
|
<a href="/pkg/database/sql/driver/#Rows.Next"><code>driver.Rows.Next</code></a> should ensure they no longer
|
||||||
|
write to a buffer assigned to the destination array outside of that call.
|
||||||
|
Drivers must be careful that underlying buffers are not modified when closing
|
||||||
|
<a href="/pkg/database/sql/driver/#Rows"><code>driver.Rows</code></a>.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
Drivers that want to construct a <a href="/pkg/database/sql/#DB"><code>sql.DB</code></a> for
|
Drivers that want to construct a <a href="/pkg/database/sql/#DB"><code>sql.DB</code></a> for
|
||||||
their clients can now implement the <a href="/pkg/database/sql/driver/#Connector"><code>Connector</code></a> interface
|
their clients can now implement the <a href="/pkg/database/sql/driver/#Connector"><code>Connector</code></a> interface
|
||||||
and call the new <a href="/pkg/database/sql/#OpenDB"><code>sql.OpenDB</code></a> function,
|
and call the new <a href="/pkg/database/sql/#OpenDB"><code>sql.OpenDB</code></a> function,
|
||||||
|
|
@ -1008,12 +1081,10 @@ now implement those interfaces.
|
||||||
<dl id="html/template"><dt><a href="/pkg/html/template/">html/template</a></dt>
|
<dl id="html/template"><dt><a href="/pkg/html/template/">html/template</a></dt>
|
||||||
<dd>
|
<dd>
|
||||||
<p>
|
<p>
|
||||||
The new actions <code>{{"{{break}}"}}</code> and <code>{{"{{continue}}"}}</code>
|
The new <a href="/pkg/html/template#Srcset"><code>Srcset</code></a> content
|
||||||
break out of the innermost <code>{{"{{range"}}</code> ...<code>}}</code> loop,
|
type allows for proper handling of values within the
|
||||||
like the corresponding Go statements.
|
<a href="https://w3c.github.io/html/semantics-embedded-content.html#element-attrdef-img-srcset"><code>srcset</code></a>
|
||||||
</p>
|
attribute of <code>img</code> tags.
|
||||||
<p>
|
|
||||||
TODO: something about the AddParseTree problem (#21844).
|
|
||||||
</p>
|
</p>
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
|
|
@ -1042,11 +1113,11 @@ compute square roots.
|
||||||
<dd>
|
<dd>
|
||||||
<p>
|
<p>
|
||||||
Branch cuts and other boundary cases in
|
Branch cuts and other boundary cases in
|
||||||
<a href="/pkg/math/cmplx/#Asin"><code>Asin<code></a>,
|
<a href="/pkg/math/cmplx/#Asin"><code>Asin</code></a>,
|
||||||
<a href="/pkg/math/cmplx/#Asinh"><code>Asinh<code></a>,
|
<a href="/pkg/math/cmplx/#Asinh"><code>Asinh</code></a>,
|
||||||
<a href="/pkg/math/cmplx/#Atan"><code>Atan<code></a>,
|
<a href="/pkg/math/cmplx/#Atan"><code>Atan</code></a>,
|
||||||
and
|
and
|
||||||
<a href="/pkg/math/cmplx/#Sqrt"><code>Sqrt<code></a>
|
<a href="/pkg/math/cmplx/#Sqrt"><code>Sqrt</code></a>
|
||||||
have been corrected to match the definitions used in the C99 standard.
|
have been corrected to match the definitions used in the C99 standard.
|
||||||
</p>
|
</p>
|
||||||
</dl>
|
</dl>
|
||||||
|
|
@ -1154,14 +1225,11 @@ The content-serving handlers also now omit the <code>Content-Type</code> header
|
||||||
if passed an invalid (non-3-digit) status code.
|
if passed an invalid (non-3-digit) status code.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<a href="/pkg/net/http/#Redirect"><code>Redirect</code></a> now sets the <code>Content-Type</code> header before writing its HTTP response.
|
<!-- CL 46631 -->
|
||||||
|
The <code>Server</code> will no longer add an implicit Content-Type when a <code>Handler</code> does not write any output.
|
||||||
</p>
|
</p>
|
||||||
</dl>
|
|
||||||
|
|
||||||
<dl id="net/http/httputil"><dt><a href="/pkg/net/http/httputil/">net/http/httputil</a></dt>
|
|
||||||
<dd>
|
|
||||||
<p>
|
<p>
|
||||||
TODO: ReverseProxy and back end errors and ModifyResponse.
|
<a href="/pkg/net/http/#Redirect"><code>Redirect</code></a> now sets the <code>Content-Type</code> header before writing its HTTP response.
|
||||||
</p>
|
</p>
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
|
|
@ -1200,7 +1268,7 @@ were not indented.
|
||||||
<dd>
|
<dd>
|
||||||
<p>
|
<p>
|
||||||
<a href="/pkg/net/url/#ResolveReference"><code>ResolveReference</code></a>
|
<a href="/pkg/net/url/#ResolveReference"><code>ResolveReference</code></a>
|
||||||
now preseves multiple leading slashes in the target URL.
|
now preserves multiple leading slashes in the target URL.
|
||||||
Previously it rewrote multiple leading slashes to a single slash,
|
Previously it rewrote multiple leading slashes to a single slash,
|
||||||
which resulted in the <a href="/pkg/net/http/#Client"><code>http.Client</code></a>
|
which resulted in the <a href="/pkg/net/http/#Client"><code>http.Client</code></a>
|
||||||
following certain redirects incorrectly.
|
following certain redirects incorrectly.
|
||||||
|
|
@ -1249,6 +1317,10 @@ and
|
||||||
that allow setting I/O deadlines when the
|
that allow setting I/O deadlines when the
|
||||||
underlying file descriptor supports non-blocking I/O operations.
|
underlying file descriptor supports non-blocking I/O operations.
|
||||||
The definition of these methods matches those in <a href="/pkg/net/#Conn"><code>net.Conn</code></a>.
|
The definition of these methods matches those in <a href="/pkg/net/#Conn"><code>net.Conn</code></a>.
|
||||||
|
If an I/O method fails due to missing a deadline, it will return a
|
||||||
|
timeout error; the
|
||||||
|
new <a href="/pkg/os/#IsTimeout"><code>IsTimeout</code></a> function
|
||||||
|
reports whether an error represents a timeout.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -1257,7 +1329,7 @@ Also matching <code>net.Conn</code>,
|
||||||
<a href="/pkg/os/#File.Close"><code>Close</code></a> method
|
<a href="/pkg/os/#File.Close"><code>Close</code></a> method
|
||||||
now guarantee that when <code>Close</code> returns,
|
now guarantee that when <code>Close</code> returns,
|
||||||
the underlying file descriptor has been closed.
|
the underlying file descriptor has been closed.
|
||||||
(In earlier releases, like for <code>net.Conn</code>'s,
|
(In earlier releases,
|
||||||
if the <code>Close</code> stopped pending I/O
|
if the <code>Close</code> stopped pending I/O
|
||||||
in other goroutines, the closing of the file descriptor could happen in one of those
|
in other goroutines, the closing of the file descriptor could happen in one of those
|
||||||
goroutines shortly after <code>Close</code> returned.)
|
goroutines shortly after <code>Close</code> returned.)
|
||||||
|
|
@ -1286,7 +1358,7 @@ in the corresponding <a href="/pkg/reflect/#StructField">StructField</a>,
|
||||||
with the result that for those fields,
|
with the result that for those fields,
|
||||||
and <a href="/pkg/reflect/#Value.CanSet"><code>Value.CanSet</code></a>
|
and <a href="/pkg/reflect/#Value.CanSet"><code>Value.CanSet</code></a>
|
||||||
incorrectly returned true and
|
incorrectly returned true and
|
||||||
and <a href="/pkg/reflect/#Value.Set"><code>Value.Set</code></a>
|
<a href="/pkg/reflect/#Value.Set"><code>Value.Set</code></a>
|
||||||
incorrectly succeeded.
|
incorrectly succeeded.
|
||||||
The underlying metadata has been corrected;
|
The underlying metadata has been corrected;
|
||||||
for those fields,
|
for those fields,
|
||||||
|
|
@ -1297,7 +1369,6 @@ that could previously unmarshal into such fields
|
||||||
but no longer can.
|
but no longer can.
|
||||||
For example, see the <a href="#encoding/json"><code>encoding/json</code> notes</a>.
|
For example, see the <a href="#encoding/json"><code>encoding/json</code> notes</a>.
|
||||||
</p>
|
</p>
|
||||||
</p>
|
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
<dl id="runtime/pprof"><dt><a href="/pkg/runtime/pprof/">runtime/pprof</a></dt>
|
<dl id="runtime/pprof"><dt><a href="/pkg/runtime/pprof/">runtime/pprof</a></dt>
|
||||||
|
|
@ -1351,15 +1422,6 @@ is now implemented.
|
||||||
</p>
|
</p>
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
<dl id="text/template"><dt><a href="/pkg/text/template/">text/template</a></dt>
|
|
||||||
<dd>
|
|
||||||
<p>
|
|
||||||
The new actions <code>{{"{{break}}"}}</code> and <code>{{"{{continue}}"}}</code>
|
|
||||||
break out of the innermost <code>{{"{{range"}}</code> ...<code>}}</code> loop,
|
|
||||||
like the corresponding Go statements.
|
|
||||||
</p>
|
|
||||||
</dl>
|
|
||||||
|
|
||||||
<dl id="time"><dt><a href="/pkg/time/">time</a></dt>
|
<dl id="time"><dt><a href="/pkg/time/">time</a></dt>
|
||||||
<dd>
|
<dd>
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -1378,7 +1440,7 @@ allows conversion of IANA time zone file data to a <a href="/pkg/time/#Location"
|
||||||
<dd>
|
<dd>
|
||||||
<p>
|
<p>
|
||||||
The <a href="/pkg/unicode/"><code>unicode</code></a> package and associated
|
The <a href="/pkg/unicode/"><code>unicode</code></a> package and associated
|
||||||
support throughout the system has been upgraded from version 9.0 to
|
support throughout the system has been upgraded from Unicode 9.0 to
|
||||||
<a href="http://www.unicode.org/versions/Unicode10.0.0/">Unicode 10.0</a>,
|
<a href="http://www.unicode.org/versions/Unicode10.0.0/">Unicode 10.0</a>,
|
||||||
which adds 8,518 new characters, including four new scripts, one new property,
|
which adds 8,518 new characters, including four new scripts, one new property,
|
||||||
a Bitcoin currency symbol, and 56 new emoji.
|
a Bitcoin currency symbol, and 56 new emoji.
|
||||||
|
|
|
||||||
|
|
@ -266,7 +266,7 @@ is now an error.
|
||||||
<p>
|
<p>
|
||||||
On the ARM, the toolchain supports "external linking", which
|
On the ARM, the toolchain supports "external linking", which
|
||||||
is a step towards being able to build shared libraries with the gc
|
is a step towards being able to build shared libraries with the gc
|
||||||
tool chain and to provide dynamic linking support for environments
|
toolchain and to provide dynamic linking support for environments
|
||||||
in which that is necessary.
|
in which that is necessary.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ The latest Go release, version 1.3, arrives six months after 1.2,
|
||||||
and contains no language changes.
|
and contains no language changes.
|
||||||
It focuses primarily on implementation work, providing
|
It focuses primarily on implementation work, providing
|
||||||
precise garbage collection,
|
precise garbage collection,
|
||||||
a major refactoring of the compiler tool chain that results in
|
a major refactoring of the compiler toolchain that results in
|
||||||
faster builds, especially for large projects,
|
faster builds, especially for large projects,
|
||||||
significant performance improvements across the board,
|
significant performance improvements across the board,
|
||||||
and support for DragonFly BSD, Solaris, Plan 9 and Google's Native Client architecture (NaCl).
|
and support for DragonFly BSD, Solaris, Plan 9 and Google's Native Client architecture (NaCl).
|
||||||
|
|
@ -285,7 +285,7 @@ building and linking with a shared library.
|
||||||
<h3 id="gc_flag">Command-line flag parsing</h3>
|
<h3 id="gc_flag">Command-line flag parsing</h3>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
In the gc tool chain, the assemblers now use the
|
In the gc toolchain, the assemblers now use the
|
||||||
same command-line flag parsing rules as the Go flag package, a departure
|
same command-line flag parsing rules as the Go flag package, a departure
|
||||||
from the traditional Unix flag parsing.
|
from the traditional Unix flag parsing.
|
||||||
This may affect scripts that invoke the tool directly.
|
This may affect scripts that invoke the tool directly.
|
||||||
|
|
|
||||||
|
|
@ -2035,4 +2035,4 @@ They are available for many combinations of architecture and operating system
|
||||||
Installation details are described on the
|
Installation details are described on the
|
||||||
<a href="/doc/install">Getting Started</a> page, while
|
<a href="/doc/install">Getting Started</a> page, while
|
||||||
the distributions themselves are listed on the
|
the distributions themselves are listed on the
|
||||||
<a href="https://golang.org/dl/">downloads page</a>.
|
<a href="/dl/">downloads page</a>.
|
||||||
|
|
|
||||||
|
|
@ -190,8 +190,8 @@ For details and background, see
|
||||||
<h2 id="tools">Tools</h2>
|
<h2 id="tools">Tools</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Finally, the Go tool chain (compilers, linkers, build tools, and so
|
Finally, the Go toolchain (compilers, linkers, build tools, and so
|
||||||
on) are under active development and may change behavior. This
|
on) is under active development and may change behavior. This
|
||||||
means, for instance, that scripts that depend on the location and
|
means, for instance, that scripts that depend on the location and
|
||||||
properties of the tools may be broken by a point release.
|
properties of the tools may be broken by a point release.
|
||||||
</p>
|
</p>
|
||||||
|
|
|
||||||
|
|
@ -479,6 +479,15 @@ as when hosting an untrusted program, the implementation could interlock
|
||||||
map access.
|
map access.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Map access is unsafe only when updates are occurring.
|
||||||
|
As long as all goroutines are only reading—looking up elements in the map,
|
||||||
|
including iterating through it using a
|
||||||
|
<code>for</code> <code>range</code> loop—and not changing the map
|
||||||
|
by assigning to elements or doing deletions,
|
||||||
|
it is safe for them to access the map concurrently without synchronization.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h3 id="language_changes">
|
<h3 id="language_changes">
|
||||||
Will you accept my language change?</h3>
|
Will you accept my language change?</h3>
|
||||||
|
|
||||||
|
|
@ -1088,24 +1097,27 @@ The <code>go get</code> command therefore uses HTTPS for safety.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
If you use <code>git</code> and prefer to push changes through SSH using your existing key
|
<code>Git</code> can be configured to authenticate over HTTPS or to use SSH in place of HTTPS.
|
||||||
it's easy to work around this. For GitHub, try one of these solutions:
|
To authenticate over HTTPS, you can add a line
|
||||||
|
to the <code>$HOME/.netrc</code> file that git consults:
|
||||||
</p>
|
</p>
|
||||||
<ul>
|
|
||||||
<li>Manually clone the repository in the expected package directory:
|
|
||||||
<pre>
|
<pre>
|
||||||
$ cd src/github.com/username
|
machine github.com login <i>USERNAME</i> password <i>APIKEY</i>
|
||||||
$ git clone git@github.com:username/package.git
|
|
||||||
</pre>
|
</pre>
|
||||||
</li>
|
<p>
|
||||||
<li>Force <code>git push</code> to use the <code>SSH</code> protocol by appending
|
For GitHub accounts, the password can be a
|
||||||
these two lines to <code>~/.gitconfig</code>:
|
<a href="https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/">personal access token</a>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<code>Git</code> can also be configured to use SSH in place of HTTPS for URLs matching a given prefix.
|
||||||
|
For example, to use SSH for all GitHub access,
|
||||||
|
add these lines to your <code>~/.gitconfig</code>:
|
||||||
|
</p>
|
||||||
<pre>
|
<pre>
|
||||||
[url "git@github.com:"]
|
[url "ssh://git@github.com/"]
|
||||||
pushInsteadOf = https://github.com/
|
insteadOf = https://github.com/
|
||||||
</pre>
|
</pre>
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h3 id="get_version">
|
<h3 id="get_version">
|
||||||
How should I manage package versions using "go get"?</h3>
|
How should I manage package versions using "go get"?</h3>
|
||||||
|
|
@ -1842,19 +1854,20 @@ supported by recent modifications to the gold linker.
|
||||||
Why is my trivial program such a large binary?</h3>
|
Why is my trivial program such a large binary?</h3>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The linker in the <code>gc</code> tool chain
|
The linker in the <code>gc</code> toolchain
|
||||||
creates statically-linked binaries by default. All Go binaries therefore include the Go
|
creates statically-linked binaries by default.
|
||||||
|
All Go binaries therefore include the Go
|
||||||
run-time, along with the run-time type information necessary to support dynamic
|
run-time, along with the run-time type information necessary to support dynamic
|
||||||
type checks, reflection, and even panic-time stack traces.
|
type checks, reflection, and even panic-time stack traces.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
A simple C "hello, world" program compiled and linked statically using gcc
|
A simple C "hello, world" program compiled and linked statically using
|
||||||
on Linux is around 750 kB,
|
gcc on Linux is around 750 kB, including an implementation of
|
||||||
including an implementation of <code>printf</code>.
|
<code>printf</code>.
|
||||||
An equivalent Go program using <code>fmt.Printf</code>
|
An equivalent Go program using
|
||||||
is around 1.5 MB, but
|
<code>fmt.Printf</code> weighs a couple of megabytes, but that includes
|
||||||
that includes more powerful run-time support and type information.
|
more powerful run-time support and type and debugging information.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h3 id="unused_variables_and_imports">
|
<h3 id="unused_variables_and_imports">
|
||||||
|
|
@ -1922,6 +1935,26 @@ eliminating the unused imports issue in practice.
|
||||||
This program is easily connected to most editors to run automatically when a Go source file is written.
|
This program is easily connected to most editors to run automatically when a Go source file is written.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<h3 id="virus">
|
||||||
|
Why does my virus-scanning software think my Go distribution or compiled binary is infected?</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
This is a common occurrence, especially on Windows machines, and is almost always a false positive.
|
||||||
|
Commercial virus scanning programs are often confused by the structure of Go binaries, which
|
||||||
|
they don't see as often as those compiled from other languages.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
If you've just installed the Go distribution and the system reports it is infected, that's certainly a mistake.
|
||||||
|
To be really thorough, you can verify the download by comparing the checksum with those on the
|
||||||
|
<a href="https://golang.org/dl/">downloads page</a>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
In any case, if you believe the report is in error, please report a bug to the supplier of your virus scanner.
|
||||||
|
Maybe in time virus scanners can learn to understand Go programs.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h2 id="Performance">Performance</h2>
|
<h2 id="Performance">Performance</h2>
|
||||||
|
|
||||||
<h3 id="Why_does_Go_perform_badly_on_benchmark_x">
|
<h3 id="Why_does_Go_perform_badly_on_benchmark_x">
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<!--{
|
<!--{
|
||||||
"Title": "The Go Programming Language Specification",
|
"Title": "The Go Programming Language Specification",
|
||||||
"Subtitle": "Version of October 25, 2017",
|
"Subtitle": "Version of May 9, 2018",
|
||||||
"Path": "/ref/spec"
|
"Path": "/ref/spec"
|
||||||
}-->
|
}-->
|
||||||
|
|
||||||
|
|
@ -694,9 +694,8 @@ TypeLit = ArrayType | StructType | PointerType | FunctionType | InterfaceType
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Named instances of the boolean, numeric, and string types are
|
The language <a href="#Predeclared_identifiers">predeclares</a> certain type names.
|
||||||
<a href="#Predeclared_identifiers">predeclared</a>.
|
Others are introduced with <a href="#Type_declarations">type declarations</a>.
|
||||||
Other named types are introduced with <a href="#Type_declarations">type declarations</a>.
|
|
||||||
<i>Composite types</i>—array, struct, pointer, function,
|
<i>Composite types</i>—array, struct, pointer, function,
|
||||||
interface, slice, map, and channel types—may be constructed using
|
interface, slice, map, and channel types—may be constructed using
|
||||||
type literals.
|
type literals.
|
||||||
|
|
@ -1025,8 +1024,8 @@ of a struct except that they cannot be used as field names in
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Given a struct type <code>S</code> and a type named <code>T</code>,
|
Given a struct type <code>S</code> and a <a href="#Type_definitions">defined type</a>
|
||||||
promoted methods are included in the method set of the struct as follows:
|
<code>T</code>, promoted methods are included in the method set of the struct as follows:
|
||||||
</p>
|
</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
|
|
@ -1453,9 +1452,9 @@ components have identical types. In detail:
|
||||||
<a href="#Exported_identifiers">Non-exported</a> method names from different
|
<a href="#Exported_identifiers">Non-exported</a> method names from different
|
||||||
packages are always different. The order of the methods is irrelevant.</li>
|
packages are always different. The order of the methods is irrelevant.</li>
|
||||||
|
|
||||||
<li>Two map types are identical if they have identical key and value types.</li>
|
<li>Two map types are identical if they have identical key and element types.</li>
|
||||||
|
|
||||||
<li>Two channel types are identical if they have identical value types and
|
<li>Two channel types are identical if they have identical element types and
|
||||||
the same direction.</li>
|
the same direction.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|
@ -1495,7 +1494,7 @@ A2 and struct{ a, b int }
|
||||||
A3 and int
|
A3 and int
|
||||||
A4, func(int, float64) *[]string, and A5
|
A4, func(int, float64) *[]string, and A5
|
||||||
|
|
||||||
B0, B0, and C0
|
B0 and C0
|
||||||
[]int and []int
|
[]int and []int
|
||||||
struct{ a, b *T5 } and struct{ a, b *T5 }
|
struct{ a, b *T5 } and struct{ a, b *T5 }
|
||||||
func(x int, y float64) *[]string, func(int, float64) (result *[]string), and A5
|
func(x int, y float64) *[]string, func(int, float64) (result *[]string), and A5
|
||||||
|
|
@ -2149,9 +2148,8 @@ to a function.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre class="ebnf">
|
<pre class="ebnf">
|
||||||
FunctionDecl = "func" FunctionName ( Function | Signature ) .
|
FunctionDecl = "func" FunctionName Signature [ FunctionBody ] .
|
||||||
FunctionName = identifier .
|
FunctionName = identifier .
|
||||||
Function = Signature FunctionBody .
|
|
||||||
FunctionBody = Block .
|
FunctionBody = Block .
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
|
|
@ -2197,7 +2195,7 @@ and associates the method with the receiver's <i>base type</i>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre class="ebnf">
|
<pre class="ebnf">
|
||||||
MethodDecl = "func" Receiver MethodName ( Function | Signature ) .
|
MethodDecl = "func" Receiver MethodName Signature [ FunctionBody ] .
|
||||||
Receiver = Parameters .
|
Receiver = Parameters .
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
|
|
@ -2519,7 +2517,7 @@ A function literal represents an anonymous <a href="#Function_declarations">func
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre class="ebnf">
|
<pre class="ebnf">
|
||||||
FunctionLit = "func" Function .
|
FunctionLit = "func" Signature FunctionBody .
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
|
|
@ -2643,8 +2641,8 @@ expression is illegal.
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li>
|
<li>
|
||||||
As an exception, if the type of <code>x</code> is a named pointer type
|
As an exception, if the type of <code>x</code> is a <a href="#Type_definitions">defined</a>
|
||||||
and <code>(*x).f</code> is a valid selector expression denoting a field
|
pointer type and <code>(*x).f</code> is a valid selector expression denoting a field
|
||||||
(but not a method), <code>x.f</code> is shorthand for <code>(*x).f</code>.
|
(but not a method), <code>x.f</code> is shorthand for <code>(*x).f</code>.
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
@ -3033,11 +3031,11 @@ For <code>a</code> of <a href="#Map_types">map type</a> <code>M</code>:
|
||||||
<a href="#Assignability">assignable</a>
|
<a href="#Assignability">assignable</a>
|
||||||
to the key type of <code>M</code></li>
|
to the key type of <code>M</code></li>
|
||||||
<li>if the map contains an entry with key <code>x</code>,
|
<li>if the map contains an entry with key <code>x</code>,
|
||||||
<code>a[x]</code> is the map value with key <code>x</code>
|
<code>a[x]</code> is the map element with key <code>x</code>
|
||||||
and the type of <code>a[x]</code> is the value type of <code>M</code></li>
|
and the type of <code>a[x]</code> is the element type of <code>M</code></li>
|
||||||
<li>if the map is <code>nil</code> or does not contain such an entry,
|
<li>if the map is <code>nil</code> or does not contain such an entry,
|
||||||
<code>a[x]</code> is the <a href="#The_zero_value">zero value</a>
|
<code>a[x]</code> is the <a href="#The_zero_value">zero value</a>
|
||||||
for the value type of <code>M</code></li>
|
for the element type of <code>M</code></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -3053,7 +3051,6 @@ used in an <a href="#Assignments">assignment</a> or initialization of the specia
|
||||||
v, ok = a[x]
|
v, ok = a[x]
|
||||||
v, ok := a[x]
|
v, ok := a[x]
|
||||||
var v, ok = a[x]
|
var v, ok = a[x]
|
||||||
var v, ok T = a[x]
|
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -3558,9 +3555,10 @@ with <code>x / y</code> truncated towards zero
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
As an exception to this rule, if the dividend <code>x</code> is the most
|
The one exception to this rule is that if the dividend <code>x</code> is
|
||||||
negative value for the int type of <code>x</code>, the quotient
|
the most negative value for the int type of <code>x</code>, the quotient
|
||||||
<code>q = x / -1</code> is equal to <code>x</code> (and <code>r = 0</code>).
|
<code>q = x / -1</code> is equal to <code>x</code> (and <code>r = 0</code>)
|
||||||
|
due to two's-complement <a href="#Integer_overflow">integer overflow</a>:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
|
|
@ -3619,15 +3617,15 @@ For unsigned integer values, the operations <code>+</code>,
|
||||||
computed modulo 2<sup><i>n</i></sup>, where <i>n</i> is the bit width of
|
computed modulo 2<sup><i>n</i></sup>, where <i>n</i> is the bit width of
|
||||||
the <a href="#Numeric_types">unsigned integer</a>'s type.
|
the <a href="#Numeric_types">unsigned integer</a>'s type.
|
||||||
Loosely speaking, these unsigned integer operations
|
Loosely speaking, these unsigned integer operations
|
||||||
discard high bits upon overflow, and programs may rely on ``wrap around''.
|
discard high bits upon overflow, and programs may rely on "wrap around".
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
For signed integers, the operations <code>+</code>,
|
For signed integers, the operations <code>+</code>,
|
||||||
<code>-</code>, <code>*</code>, and <code><<</code> may legally
|
<code>-</code>, <code>*</code>, <code>/</code>, and <code><<</code> may legally
|
||||||
overflow and the resulting value exists and is deterministically defined
|
overflow and the resulting value exists and is deterministically defined
|
||||||
by the signed integer representation, the operation, and its operands.
|
by the signed integer representation, the operation, and its operands.
|
||||||
No exception is raised as a result of overflow. A
|
No exception is raised as a result of overflow.
|
||||||
compiler may not optimize code under the assumption that overflow does
|
A compiler may not optimize code under the assumption that overflow does
|
||||||
not occur. For instance, it may not assume that <code>x < x + 1</code> is always true.
|
not occur. For instance, it may not assume that <code>x < x + 1</code> is always true.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
@ -4162,11 +4160,6 @@ operands and are evaluated at compile time.
|
||||||
Untyped boolean, numeric, and string constants may be used as operands
|
Untyped boolean, numeric, and string constants may be used as operands
|
||||||
wherever it is legal to use an operand of boolean, numeric, or string type,
|
wherever it is legal to use an operand of boolean, numeric, or string type,
|
||||||
respectively.
|
respectively.
|
||||||
Except for shift operations, if the operands of a binary operation are
|
|
||||||
different kinds of untyped constants, the operation and, for non-boolean operations, the result use
|
|
||||||
the kind that appears later in this list: integer, rune, floating-point, complex.
|
|
||||||
For example, an untyped integer constant divided by an
|
|
||||||
untyped complex constant yields an untyped complex constant.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -4176,9 +4169,17 @@ an untyped boolean constant. If the left operand of a constant
|
||||||
result is an integer constant; otherwise it is a constant of the same
|
result is an integer constant; otherwise it is a constant of the same
|
||||||
type as the left operand, which must be of
|
type as the left operand, which must be of
|
||||||
<a href="#Numeric_types">integer type</a>.
|
<a href="#Numeric_types">integer type</a>.
|
||||||
Applying all other operators to untyped constants results in an untyped
|
</p>
|
||||||
constant of the same kind (that is, a boolean, integer, floating-point,
|
|
||||||
complex, or string constant).
|
<p>
|
||||||
|
Any other operation on untyped constants results in an untyped constant of the
|
||||||
|
same kind; that is, a boolean, integer, floating-point, complex, or string
|
||||||
|
constant.
|
||||||
|
If the untyped operands of a binary operation (other than a shift) are of
|
||||||
|
different kinds, the result is of the operand's kind that appears later in this
|
||||||
|
list: integer, rune, floating-point, complex.
|
||||||
|
For example, an untyped integer constant divided by an
|
||||||
|
untyped complex constant yields an untyped complex constant.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
|
|
@ -4356,7 +4357,9 @@ SimpleStmt = EmptyStmt | ExpressionStmt | SendStmt | IncDecStmt | Assignment | S
|
||||||
<h3 id="Terminating_statements">Terminating statements</h3>
|
<h3 id="Terminating_statements">Terminating statements</h3>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
A terminating statement is one of the following:
|
A <i>terminating statement</i> prevents execution of all statements that lexically
|
||||||
|
appear after it in the same <a href="#Blocks">block</a>. The following statements
|
||||||
|
are terminating:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<ol>
|
<ol>
|
||||||
|
|
@ -5120,7 +5123,7 @@ for i, s := range a {
|
||||||
}
|
}
|
||||||
|
|
||||||
var key string
|
var key string
|
||||||
var val interface {} // value type of m is assignable to val
|
var val interface {} // element type of m is assignable to val
|
||||||
m := map[string]int{"mon":0, "tue":1, "wed":2, "thu":3, "fri":4, "sat":5, "sun":6}
|
m := map[string]int{"mon":0, "tue":1, "wed":2, "thu":3, "fri":4, "sat":5, "sun":6}
|
||||||
for key, val = range m {
|
for key, val = range m {
|
||||||
h(key, val)
|
h(key, val)
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ packages, though, read on.
|
||||||
<div class="detail">
|
<div class="detail">
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
There are two official Go compiler tool chains.
|
There are two official Go compiler toolchains.
|
||||||
This document focuses on the <code>gc</code> Go
|
This document focuses on the <code>gc</code> Go
|
||||||
compiler and tools.
|
compiler and tools.
|
||||||
For information on how to work on <code>gccgo</code>, a more traditional
|
For information on how to work on <code>gccgo</code>, a more traditional
|
||||||
|
|
@ -119,7 +119,7 @@ Go does not support CentOS 6 on these systems.
|
||||||
<h2 id="go14">Install Go compiler binaries</h2>
|
<h2 id="go14">Install Go compiler binaries</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The Go tool chain is written in Go. To build it, you need a Go compiler installed.
|
The Go toolchain is written in Go. To build it, you need a Go compiler installed.
|
||||||
The scripts that do the initial build of the tools look for an existing Go tool
|
The scripts that do the initial build of the tools look for an existing Go tool
|
||||||
chain in <code>$GOROOT_BOOTSTRAP</code>.
|
chain in <code>$GOROOT_BOOTSTRAP</code>.
|
||||||
If unset, the default value of <code>GOROOT_BOOTSTRAP</code>
|
If unset, the default value of <code>GOROOT_BOOTSTRAP</code>
|
||||||
|
|
@ -127,26 +127,26 @@ is <code>$HOME/go1.4</code>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
There are many options for the bootstrap tool chain.
|
There are many options for the bootstrap toolchain.
|
||||||
After obtaining one, set <code>GOROOT_BOOTSTRAP</code> to the
|
After obtaining one, set <code>GOROOT_BOOTSTRAP</code> to the
|
||||||
directory containing the unpacked tree.
|
directory containing the unpacked tree.
|
||||||
For example, <code>$GOROOT_BOOTSTRAP/bin/go</code> should be
|
For example, <code>$GOROOT_BOOTSTRAP/bin/go</code> should be
|
||||||
the <code>go</code> command binary for the bootstrap tool chain.
|
the <code>go</code> command binary for the bootstrap toolchain.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
To use a binary release as a bootstrap tool chain, see
|
To use a binary release as a bootstrap toolchain, see
|
||||||
<a href="/dl/">the downloads page</a> or use any other
|
<a href="/dl/">the downloads page</a> or use any other
|
||||||
packaged Go distribution.
|
packaged Go distribution.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
To build a bootstrap tool chain from source, use
|
To build a bootstrap toolchain from source, use
|
||||||
either the git branch <code>release-branch.go1.4</code> or
|
either the git branch <code>release-branch.go1.4</code> or
|
||||||
<a href="https://dl.google.com/go/go1.4-bootstrap-20171003.tar.gz">go1.4-bootstrap-20171003.tar.gz</a>,
|
<a href="https://dl.google.com/go/go1.4-bootstrap-20171003.tar.gz">go1.4-bootstrap-20171003.tar.gz</a>,
|
||||||
which contains the Go 1.4 source code plus accumulated fixes
|
which contains the Go 1.4 source code plus accumulated fixes
|
||||||
to keep the tools running on newer operating systems.
|
to keep the tools running on newer operating systems.
|
||||||
(Go 1.4 was the last distribution in which the tool chain was written in C.)
|
(Go 1.4 was the last distribution in which the toolchain was written in C.)
|
||||||
After unpacking the Go 1.4 source, <code>cd</code> to
|
After unpacking the Go 1.4 source, <code>cd</code> to
|
||||||
the <code>src</code> subdirectory, set <code>CGO_ENABLED=0</code> in
|
the <code>src</code> subdirectory, set <code>CGO_ENABLED=0</code> in
|
||||||
the environment, and run <code>make.bash</code> (or,
|
the environment, and run <code>make.bash</code> (or,
|
||||||
|
|
@ -154,7 +154,7 @@ on Windows, <code>make.bat</code>).
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
To cross-compile a bootstrap tool chain from source, which is
|
To cross-compile a bootstrap toolchain from source, which is
|
||||||
necessary on systems Go 1.4 did not target (for
|
necessary on systems Go 1.4 did not target (for
|
||||||
example, <code>linux/ppc64le</code>), install Go on a different system
|
example, <code>linux/ppc64le</code>), install Go on a different system
|
||||||
and run <a href="/src/bootstrap.bash">bootstrap.bash</a>.
|
and run <a href="/src/bootstrap.bash">bootstrap.bash</a>.
|
||||||
|
|
@ -307,7 +307,7 @@ package main
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
fmt.Printf("hello, world\n")
|
fmt.Printf("hello, world\n")
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
|
|
@ -446,6 +446,7 @@ defaults to the parent of the directory where <code>all.bash</code> was run.
|
||||||
There is no need to set this unless you want to switch between multiple
|
There is no need to set this unless you want to switch between multiple
|
||||||
local copies of the repository.
|
local copies of the repository.
|
||||||
</p>
|
</p>
|
||||||
|
</li>
|
||||||
|
|
||||||
<li><code>$GOROOT_FINAL</code>
|
<li><code>$GOROOT_FINAL</code>
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -456,12 +457,14 @@ If you want to build the Go tree in one location
|
||||||
but move it elsewhere after the build, set
|
but move it elsewhere after the build, set
|
||||||
<code>$GOROOT_FINAL</code> to the eventual location.
|
<code>$GOROOT_FINAL</code> to the eventual location.
|
||||||
</p>
|
</p>
|
||||||
|
</li>
|
||||||
|
|
||||||
<li><code>$GOOS</code> and <code>$GOARCH</code>
|
<li><code>$GOOS</code> and <code>$GOARCH</code>
|
||||||
<p>
|
<p>
|
||||||
The name of the target operating system and compilation architecture.
|
The name of the target operating system and compilation architecture.
|
||||||
These default to the values of <code>$GOHOSTOS</code> and
|
These default to the values of <code>$GOHOSTOS</code> and
|
||||||
<code>$GOHOSTARCH</code> respectively (described below).
|
<code>$GOHOSTARCH</code> respectively (described below).
|
||||||
|
</li>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Choices for <code>$GOOS</code> are
|
Choices for <code>$GOOS</code> are
|
||||||
|
|
@ -582,6 +585,7 @@ The name of the host operating system and compilation architecture.
|
||||||
These default to the local system's operating system and
|
These default to the local system's operating system and
|
||||||
architecture.
|
architecture.
|
||||||
</p>
|
</p>
|
||||||
|
</li>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Valid choices are the same as for <code>$GOOS</code> and
|
Valid choices are the same as for <code>$GOOS</code> and
|
||||||
|
|
@ -600,6 +604,7 @@ directory to your <code>$PATH</code>, so you can use the tools.
|
||||||
If <code>$GOBIN</code> is set, the <a href="/cmd/go">go command</a>
|
If <code>$GOBIN</code> is set, the <a href="/cmd/go">go command</a>
|
||||||
installs all commands there.
|
installs all commands there.
|
||||||
</p>
|
</p>
|
||||||
|
</li>
|
||||||
|
|
||||||
<li><code>$GO386</code> (for <code>386</code> only, default is auto-detected
|
<li><code>$GO386</code> (for <code>386</code> only, default is auto-detected
|
||||||
if built on either <code>386</code> or <code>amd64</code>, <code>387</code> otherwise)
|
if built on either <code>386</code> or <code>amd64</code>, <code>387</code> otherwise)
|
||||||
|
|
@ -609,9 +614,10 @@ This controls the code generated by gc to use either the 387 floating-point unit
|
||||||
floating point computations.
|
floating point computations.
|
||||||
</p>
|
</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li><code>GO386=387</code>: use x87 for floating point operations; should support all x86 chips (Pentium MMX or later).
|
<li><code>GO386=387</code>: use x87 for floating point operations; should support all x86 chips (Pentium MMX or later).</li>
|
||||||
<li><code>GO386=sse2</code>: use SSE2 for floating point operations; has better performance than 387, but only available on Pentium 4/Opteron/Athlon 64 or later.
|
<li><code>GO386=sse2</code>: use SSE2 for floating point operations; has better performance than 387, but only available on Pentium 4/Opteron/Athlon 64 or later.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
</li>
|
||||||
|
|
||||||
<li><code>$GOARM</code> (for <code>arm</code> only; default is auto-detected if building
|
<li><code>$GOARM</code> (for <code>arm</code> only; default is auto-detected if building
|
||||||
on the target processor, 6 if not)
|
on the target processor, 6 if not)
|
||||||
|
|
@ -620,9 +626,9 @@ This sets the ARM floating point co-processor architecture version the run-time
|
||||||
should target. If you are compiling on the target system, its value will be auto-detected.
|
should target. If you are compiling on the target system, its value will be auto-detected.
|
||||||
</p>
|
</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li><code>GOARM=5</code>: use software floating point; when CPU doesn't have VFP co-processor
|
<li><code>GOARM=5</code>: use software floating point; when CPU doesn't have VFP co-processor</li>
|
||||||
<li><code>GOARM=6</code>: use VFPv1 only; default if cross compiling; usually ARM11 or better cores (VFPv2 or better is also supported)
|
<li><code>GOARM=6</code>: use VFPv1 only; default if cross compiling; usually ARM11 or better cores (VFPv2 or better is also supported)</li>
|
||||||
<li><code>GOARM=7</code>: use VFPv3; usually Cortex-A cores
|
<li><code>GOARM=7</code>: use VFPv3; usually Cortex-A cores</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p>
|
<p>
|
||||||
If in doubt, leave this variable unset, and adjust it if required
|
If in doubt, leave this variable unset, and adjust it if required
|
||||||
|
|
@ -631,6 +637,17 @@ The <a href="//golang.org/wiki/GoArm">GoARM</a> page
|
||||||
on the <a href="//golang.org/wiki">Go community wiki</a>
|
on the <a href="//golang.org/wiki">Go community wiki</a>
|
||||||
contains further details regarding Go's ARM support.
|
contains further details regarding Go's ARM support.
|
||||||
</p>
|
</p>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li><code>$GOMIPS</code> (for <code>mips</code> and <code>mipsle</code> only)
|
||||||
|
<p>
|
||||||
|
This sets whether to use floating point instructions.
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li><code>GOMIPS=hardfloat</code>: use floating point instructions (the default)</li>
|
||||||
|
<li><code>GOMIPS=softfloat</code>: use soft floating point</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,14 +8,14 @@
|
||||||
<h2 id="download">Download the Go distribution</h2>
|
<h2 id="download">Download the Go distribution</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<a href="https://golang.org/dl/" id="start" class="download">
|
<a href="/dl/" id="start" class="download">
|
||||||
<span class="big">Download Go</span>
|
<span class="big">Download Go</span>
|
||||||
<span class="desc">Click here to visit the downloads page</span>
|
<span class="desc">Click here to visit the downloads page</span>
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<a href="https://golang.org/dl/" target="_blank">Official binary
|
<a href="/dl/" target="_blank">Official binary
|
||||||
distributions</a> are available for the FreeBSD (release 10-STABLE and above),
|
distributions</a> are available for the FreeBSD (release 10-STABLE and above),
|
||||||
Linux, Mac OS X (10.8 and above), and Windows operating systems and
|
Linux, Mac OS X (10.8 and above), and Windows operating systems and
|
||||||
the 32-bit (<code>386</code>) and 64-bit (<code>amd64</code>) x86 processor
|
the 32-bit (<code>386</code>) and 64-bit (<code>amd64</code>) x86 processor
|
||||||
|
|
@ -33,7 +33,7 @@ system and architecture, try
|
||||||
<h2 id="requirements">System requirements</h2>
|
<h2 id="requirements">System requirements</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Go <a href="https://golang.org/dl/">binary distributions</a> are available for these supported operating systems and architectures.
|
Go <a href="/dl/">binary distributions</a> are available for these supported operating systems and architectures.
|
||||||
Please ensure your system meets these requirements before proceeding.
|
Please ensure your system meets these requirements before proceeding.
|
||||||
If your OS or architecture is not on the list, you may be able to
|
If your OS or architecture is not on the list, you may be able to
|
||||||
<a href="/doc/install/source">install from source</a> or
|
<a href="/doc/install/source">install from source</a> or
|
||||||
|
|
@ -77,7 +77,7 @@ first <a href="#uninstall">remove the existing version</a>.
|
||||||
<h3 id="tarball">Linux, Mac OS X, and FreeBSD tarballs</h3>
|
<h3 id="tarball">Linux, Mac OS X, and FreeBSD tarballs</h3>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<a href="https://golang.org/dl/">Download the archive</a>
|
<a href="/dl/">Download the archive</a>
|
||||||
and extract it into <code>/usr/local</code>, creating a Go tree in
|
and extract it into <code>/usr/local</code>, creating a Go tree in
|
||||||
<code>/usr/local/go</code>. For example:
|
<code>/usr/local/go</code>. For example:
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -106,6 +106,14 @@ variable. You can do this by adding this line to your <code>/etc/profile</code>
|
||||||
export PATH=$PATH:/usr/local/go/bin
|
export PATH=$PATH:/usr/local/go/bin
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<b>Note</b>: changes made to a <code>profile</code> file may not apply until the
|
||||||
|
next time you log into your computer.
|
||||||
|
To apply the changes immediately, just run the shell commands directly
|
||||||
|
or execute them from the profile using a command such as
|
||||||
|
<code>source $HOME/.profile</code>.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h4 id="tarball_non_standard">Installing to a custom location</h4>
|
<h4 id="tarball_non_standard">Installing to a custom location</h4>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -138,7 +146,7 @@ location.
|
||||||
<h3 id="osx">Mac OS X package installer</h3>
|
<h3 id="osx">Mac OS X package installer</h3>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<a href="https://golang.org/dl/">Download the package file</a>,
|
<a href="/dl/">Download the package file</a>,
|
||||||
open it, and follow the prompts to install the Go tools.
|
open it, and follow the prompts to install the Go tools.
|
||||||
The package installs the Go distribution to <code>/usr/local/go</code>.
|
The package installs the Go distribution to <code>/usr/local/go</code>.
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -167,7 +175,7 @@ MSI installer that configures your installation automatically.
|
||||||
<h4 id="windows_msi">MSI installer</h4>
|
<h4 id="windows_msi">MSI installer</h4>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Open the <a href="https://golang.org/dl/">MSI file</a>
|
Open the <a href="/dl/">MSI file</a>
|
||||||
and follow the prompts to install the Go tools.
|
and follow the prompts to install the Go tools.
|
||||||
By default, the installer puts the Go distribution in <code>c:\Go</code>.
|
By default, the installer puts the Go distribution in <code>c:\Go</code>.
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -185,7 +193,7 @@ command prompts for the change to take effect.
|
||||||
<h4 id="windows_zip">Zip archive</h4>
|
<h4 id="windows_zip">Zip archive</h4>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<a href="https://golang.org/dl/">Download the zip file</a> and extract it into the directory of your choice (we suggest <code>c:\Go</code>).
|
<a href="/dl/">Download the zip file</a> and extract it into the directory of your choice (we suggest <code>c:\Go</code>).
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -236,7 +244,7 @@ package main
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
fmt.Printf("hello, world\n")
|
fmt.Printf("hello, world\n")
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
|
|
@ -278,7 +286,7 @@ If you see the "hello, world" message then your Go installation is working.
|
||||||
<p>
|
<p>
|
||||||
You can run <code>go</code> <code>install</code> to install the binary into
|
You can run <code>go</code> <code>install</code> to install the binary into
|
||||||
your workspace's <code>bin</code> directory
|
your workspace's <code>bin</code> directory
|
||||||
or <code>go</code> <code>clean</code> to remove it.
|
or <code>go</code> <code>clean</code> <code>-i</code> to remove it.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,11 @@ func viewRecord(w http.ResponseWriter, r *http.Request) {
|
||||||
key := datastore.NewKey(c, "Record", r.FormValue("id"), 0, nil)
|
key := datastore.NewKey(c, "Record", r.FormValue("id"), 0, nil)
|
||||||
record := new(Record)
|
record := new(Record)
|
||||||
if err := datastore.Get(c, key, record); err != nil {
|
if err := datastore.Get(c, key, record); err != nil {
|
||||||
http.Error(w, err.Error(), 500)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err := viewTemplate.Execute(w, record); err != nil {
|
if err := viewTemplate.Execute(w, record); err != nil {
|
||||||
http.Error(w, err.Error(), 500)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ type appHandler func(http.ResponseWriter, *http.Request) error
|
||||||
|
|
||||||
func (fn appHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
func (fn appHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
if err := fn(w, r); err != nil {
|
if err := fn(w, r); err != nil {
|
||||||
http.Error(w, err.Error(), 500)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ simple, reliable, and efficient software.
|
||||||
|
|
||||||
<div id="gopher"></div>
|
<div id="gopher"></div>
|
||||||
|
|
||||||
<a href="https://golang.org/dl/" id="start">
|
<a href="/dl/" id="start">
|
||||||
<span class="big">Download Go</span>
|
<span class="big">Download Go</span>
|
||||||
<span class="desc">
|
<span class="desc">
|
||||||
Binary distributions available for<br>
|
Binary distributions available for<br>
|
||||||
|
|
@ -74,7 +74,7 @@ Linux, Mac OS X, Windows, and more.
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<div id="video">
|
<div id="video">
|
||||||
<div class="rootHeading">Featured video</div>
|
<div class="rootHeading">Featured video</div>
|
||||||
<iframe width="415" height="241" src="//www.youtube.com/embed/ytEkHepK08c" frameborder="0" allowfullscreen></iframe>
|
<div class="js-frontpage-video" style="--aspect-ratio-padding: 58.07%;"><iframe width="415" height="241" src="//www.youtube.com/embed/ytEkHepK08c" frameborder="0" allowfullscreen></iframe></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -153,6 +153,10 @@ Linux, Mac OS X, Windows, and more.
|
||||||
];
|
];
|
||||||
var v = videos[Math.floor(Math.random()*videos.length)];
|
var v = videos[Math.floor(Math.random()*videos.length)];
|
||||||
$('#video iframe').attr('height', v.h).attr('src', v.s);
|
$('#video iframe').attr('height', v.h).attr('src', v.s);
|
||||||
|
// Compute the aspect ratio (as a percentage) of the video
|
||||||
|
// using the fixed width 415 and the height of the current video, v.h.
|
||||||
|
var ar = 100*v.h/415;
|
||||||
|
$('.js-frontpage-video').attr('style', '--aspect-ratio-padding: ' + ar + '%;');
|
||||||
});
|
});
|
||||||
|
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ the code and data maintained as part of the IANA Time Zone Database.
|
||||||
The IANA asserts that the database is in the public domain.
|
The IANA asserts that the database is in the public domain.
|
||||||
|
|
||||||
For more information, see
|
For more information, see
|
||||||
http://www.iana.org/time-zones
|
https://www.iana.org/time-zones
|
||||||
ftp://ftp.iana.org/tz/code/tz-link.htm
|
ftp://ftp.iana.org/tz/code/tz-link.htm
|
||||||
http://tools.ietf.org/html/rfc6557
|
http://tools.ietf.org/html/rfc6557
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
# This script rebuilds the time zone files using files
|
# This script rebuilds the time zone files using files
|
||||||
# downloaded from the ICANN/IANA distribution.
|
# downloaded from the ICANN/IANA distribution.
|
||||||
# Consult http://www.iana.org/time-zones for the latest versions.
|
# Consult https://www.iana.org/time-zones for the latest versions.
|
||||||
|
|
||||||
# Versions to use.
|
# Versions to use.
|
||||||
CODE=2017c
|
CODE=2017c
|
||||||
|
|
@ -16,8 +16,8 @@ rm -rf work
|
||||||
mkdir work
|
mkdir work
|
||||||
cd work
|
cd work
|
||||||
mkdir zoneinfo
|
mkdir zoneinfo
|
||||||
curl -O http://www.iana.org/time-zones/repository/releases/tzcode$CODE.tar.gz
|
curl -L -O https://www.iana.org/time-zones/repository/releases/tzcode$CODE.tar.gz
|
||||||
curl -O http://www.iana.org/time-zones/repository/releases/tzdata$DATA.tar.gz
|
curl -L -O https://www.iana.org/time-zones/repository/releases/tzdata$DATA.tar.gz
|
||||||
tar xzf tzcode$CODE.tar.gz
|
tar xzf tzcode$CODE.tar.gz
|
||||||
tar xzf tzdata$DATA.tar.gz
|
tar xzf tzdata$DATA.tar.gz
|
||||||
|
|
||||||
|
|
@ -48,4 +48,3 @@ else
|
||||||
rm -rf work
|
rm -rf work
|
||||||
fi
|
fi
|
||||||
echo New time zone files in zoneinfo.zip.
|
echo New time zone files in zoneinfo.zip.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,4 +8,17 @@ mobile subrepository:
|
||||||
|
|
||||||
To run the standard library tests, see androidtest.bash. Run it as
|
To run the standard library tests, see androidtest.bash. Run it as
|
||||||
|
|
||||||
CC_FOR_TARGET=.../ndk-gcc GOARCH=arm GOARM=7 ./androidtest.bash
|
CC_FOR_TARGET=$STANDALONE_NDK_PATH/bin/clang GOARCH=arm64 ./androidtest.bash
|
||||||
|
|
||||||
|
To create a standalone android NDK tool chain, follow the instructions on
|
||||||
|
|
||||||
|
https://developer.android.com/ndk/guides/standalone_toolchain
|
||||||
|
|
||||||
|
To run tests on the Android device, add the bin directory to PATH so the
|
||||||
|
go tool can find the go_android_$GOARCH_exec wrapper generated by
|
||||||
|
androidtest.bash. Then, use the same GOARCH as when androidtest.bash ran
|
||||||
|
and set GOOS to android. For example, to run the go1 benchmarks
|
||||||
|
|
||||||
|
export PATH=$GOROOT/bin:$PATH
|
||||||
|
cd $GOROOT/test/bench/go1/
|
||||||
|
GOOS=android GOARCH=arm64 go test -bench=. -count=N -timeout=T
|
||||||
|
|
@ -21,6 +21,9 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func run(args ...string) string {
|
func run(args ...string) string {
|
||||||
|
if flags := os.Getenv("GOANDROID_ADB_FLAGS"); flags != "" {
|
||||||
|
args = append(strings.Split(flags, " "), args...)
|
||||||
|
}
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
cmd := exec.Command("adb", args...)
|
cmd := exec.Command("adb", args...)
|
||||||
cmd.Stdout = io.MultiWriter(os.Stdout, buf)
|
cmd.Stdout = io.MultiWriter(os.Stdout, buf)
|
||||||
|
|
|
||||||
|
|
@ -349,6 +349,14 @@ var ptrTests = []ptrTest{
|
||||||
body: `var wg sync.WaitGroup; wg.Add(100); for i := 0; i < 100; i++ { go func(i int) { for j := 0; j < 100; j++ { C.f(); runtime.GOMAXPROCS(i) }; wg.Done() }(i) }; wg.Wait()`,
|
body: `var wg sync.WaitGroup; wg.Add(100); for i := 0; i < 100; i++ { go func(i int) { for j := 0; j < 100; j++ { C.f(); runtime.GOMAXPROCS(i) }; wg.Done() }(i) }; wg.Wait()`,
|
||||||
fail: false,
|
fail: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
// Test poller deadline with cgocheck=2. Issue #23435.
|
||||||
|
name: "deadline",
|
||||||
|
c: `#define US 10`,
|
||||||
|
imports: []string{"os", "time"},
|
||||||
|
body: `r, _, _ := os.Pipe(); r.SetDeadline(time.Now().Add(C.US * time.Microsecond))`,
|
||||||
|
fail: false,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPointerChecks(t *testing.T) {
|
func TestPointerChecks(t *testing.T) {
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#cgo LDFLAGS: -c
|
#cgo LDFLAGS: -L/nonexist
|
||||||
|
|
||||||
void test() {
|
void test() {
|
||||||
xxx; // ERROR HERE
|
xxx; // ERROR HERE
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,8 @@ struct S {
|
||||||
int x;
|
int x;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const char *cstr = "abcefghijklmnopqrstuvwxyzABCEFGHIJKLMNOPQRSTUVWXYZ1234567890";
|
||||||
|
|
||||||
extern enum E myConstFunc(struct S* const ctx, int const id, struct S **const filter);
|
extern enum E myConstFunc(struct S* const ctx, int const id, struct S **const filter);
|
||||||
|
|
||||||
enum E myConstFunc(struct S *const ctx, int const id, struct S **const filter) { return 0; }
|
enum E myConstFunc(struct S *const ctx, int const id, struct S **const filter) { return 0; }
|
||||||
|
|
@ -149,6 +151,18 @@ func benchCgoCall(b *testing.B) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var sinkString string
|
||||||
|
|
||||||
|
func benchGoString(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
sinkString = C.GoString(C.cstr)
|
||||||
|
}
|
||||||
|
const want = "abcefghijklmnopqrstuvwxyzABCEFGHIJKLMNOPQRSTUVWXYZ1234567890"
|
||||||
|
if sinkString != want {
|
||||||
|
b.Fatalf("%q != %q", sinkString, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Issue 2470.
|
// Issue 2470.
|
||||||
func testUnsignedInt(t *testing.T) {
|
func testUnsignedInt(t *testing.T) {
|
||||||
a := (int64)(C.UINT32VAL)
|
a := (int64)(C.UINT32VAL)
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ func testBuildID(t *testing.T) {
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
|
||||||
c := 0
|
c := 0
|
||||||
|
sections:
|
||||||
for i, s := range f.Sections {
|
for i, s := range f.Sections {
|
||||||
if s.Type != elf.SHT_NOTE {
|
if s.Type != elf.SHT_NOTE {
|
||||||
continue
|
continue
|
||||||
|
|
@ -47,7 +48,7 @@ func testBuildID(t *testing.T) {
|
||||||
|
|
||||||
if len(d) < 12 {
|
if len(d) < 12 {
|
||||||
t.Logf("note section %d too short (%d < 12)", i, len(d))
|
t.Logf("note section %d too short (%d < 12)", i, len(d))
|
||||||
continue
|
continue sections
|
||||||
}
|
}
|
||||||
|
|
||||||
namesz := f.ByteOrder.Uint32(d)
|
namesz := f.ByteOrder.Uint32(d)
|
||||||
|
|
@ -59,7 +60,7 @@ func testBuildID(t *testing.T) {
|
||||||
|
|
||||||
if int(12+an+ad) > len(d) {
|
if int(12+an+ad) > len(d) {
|
||||||
t.Logf("note section %d too short for header (%d < 12 + align(%d,4) + align(%d,4))", i, len(d), namesz, descsz)
|
t.Logf("note section %d too short for header (%d < 12 + align(%d,4) + align(%d,4))", i, len(d), namesz, descsz)
|
||||||
continue
|
continue sections
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3 == NT_GNU_BUILD_ID
|
// 3 == NT_GNU_BUILD_ID
|
||||||
|
|
|
||||||
|
|
@ -86,5 +86,9 @@ func Test21809(t *testing.T) { test21809(t) }
|
||||||
func Test6907(t *testing.T) { test6907(t) }
|
func Test6907(t *testing.T) { test6907(t) }
|
||||||
func Test6907Go(t *testing.T) { test6907Go(t) }
|
func Test6907Go(t *testing.T) { test6907Go(t) }
|
||||||
func Test21897(t *testing.T) { test21897(t) }
|
func Test21897(t *testing.T) { test21897(t) }
|
||||||
|
func Test22906(t *testing.T) { test22906(t) }
|
||||||
|
func Test24206(t *testing.T) { test24206(t) }
|
||||||
|
func Test25143(t *testing.T) { test25143(t) }
|
||||||
|
|
||||||
func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) }
|
func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) }
|
||||||
|
func BenchmarkGoString(b *testing.B) { benchGoString(b) }
|
||||||
|
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
// Copyright 2015 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.
|
|
||||||
|
|
||||||
// Issue 19832. Functions taking a pointer typedef were being expanded and triggering a compiler error.
|
|
||||||
|
|
||||||
package cgotest
|
|
||||||
|
|
||||||
// typedef struct { int i; } *PS;
|
|
||||||
// void T19832(PS p) {}
|
|
||||||
import "C"
|
|
||||||
import "testing"
|
|
||||||
|
|
||||||
func test19832(t *testing.T) {
|
|
||||||
C.T19832(nil)
|
|
||||||
}
|
|
||||||
54
misc/cgo/test/issue24206.go
Normal file
54
misc/cgo/test/issue24206.go
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
// +build amd64,linux
|
||||||
|
|
||||||
|
// Copyright 2018 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 cgotest
|
||||||
|
|
||||||
|
// Test that C.GoString uses IndexByte in safe manner.
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
// Returns string with null byte at the last valid address
|
||||||
|
char* dangerousString1() {
|
||||||
|
int pageSize = 4096;
|
||||||
|
char *data = mmap(0, 2 * pageSize, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, 0, 0);
|
||||||
|
mprotect(data + pageSize,pageSize,PROT_NONE);
|
||||||
|
int start = pageSize - 123 - 1; // last 123 bytes of first page + 1 null byte
|
||||||
|
int i = start;
|
||||||
|
for (; i < pageSize; i++) {
|
||||||
|
data[i] = 'x';
|
||||||
|
}
|
||||||
|
data[pageSize -1 ] = 0;
|
||||||
|
return data+start;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* dangerousString2() {
|
||||||
|
int pageSize = 4096;
|
||||||
|
char *data = mmap(0, 3 * pageSize, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, 0, 0);
|
||||||
|
mprotect(data + 2 * pageSize,pageSize,PROT_NONE);
|
||||||
|
int start = pageSize - 123 - 1; // last 123 bytes of first page + 1 null byte
|
||||||
|
int i = start;
|
||||||
|
for (; i < 2 * pageSize; i++) {
|
||||||
|
data[i] = 'x';
|
||||||
|
}
|
||||||
|
data[2*pageSize -1 ] = 0;
|
||||||
|
return data+start;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func test24206(t *testing.T) {
|
||||||
|
if l := len(C.GoString(C.dangerousString1())); l != 123 {
|
||||||
|
t.Errorf("Incorrect string length - got %d, want 123", l)
|
||||||
|
}
|
||||||
|
if l := len(C.GoString(C.dangerousString2())); l != 4096+123 {
|
||||||
|
t.Errorf("Incorrect string length - got %d, want %d", l, 4096+123)
|
||||||
|
}
|
||||||
|
}
|
||||||
13
misc/cgo/test/issue24206_generic.go
Normal file
13
misc/cgo/test/issue24206_generic.go
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
// +build !amd64 !linux
|
||||||
|
|
||||||
|
// Copyright 2018 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 cgotest
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func test24206(t *testing.T) {
|
||||||
|
t.Skip("Skipping on non-amd64 or non-linux system")
|
||||||
|
}
|
||||||
22
misc/cgo/test/issue25143.go
Normal file
22
misc/cgo/test/issue25143.go
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
// Copyright 2018 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 cgotest
|
||||||
|
|
||||||
|
import "C"
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func issue25143sum(ns ...C.int) C.int {
|
||||||
|
total := C.int(0)
|
||||||
|
for _, n := range ns {
|
||||||
|
total += n
|
||||||
|
}
|
||||||
|
return total
|
||||||
|
}
|
||||||
|
|
||||||
|
func test25143(t *testing.T) {
|
||||||
|
if got, want := issue25143sum(1, 2, 3), C.int(6); got != want {
|
||||||
|
t.Errorf("issue25143sum(1, 2, 3) == %v, expected %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,6 +4,25 @@
|
||||||
|
|
||||||
// +build !windows
|
// +build !windows
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
|
||||||
|
// Write our own versions of dlopen/dlsym/dlclose so that we represent
|
||||||
|
// the opaque handle as a Go uintptr rather than a Go pointer to avoid
|
||||||
|
// garbage collector confusion. See issue 23663.
|
||||||
|
|
||||||
|
uintptr_t dlopen4029(char* name, int flags) {
|
||||||
|
return (uintptr_t)(dlopen(name, flags));
|
||||||
|
}
|
||||||
|
|
||||||
|
uintptr_t dlsym4029(uintptr_t handle, char* name) {
|
||||||
|
return (uintptr_t)(dlsym((void*)(handle), name));
|
||||||
|
}
|
||||||
|
|
||||||
|
int dlclose4029(uintptr_t handle) {
|
||||||
|
return dlclose((void*)(handle));
|
||||||
|
}
|
||||||
|
|
||||||
void call4029(void *arg) {
|
void call4029(void *arg) {
|
||||||
void (*fn)(void) = arg;
|
void (*fn)(void) = arg;
|
||||||
fn();
|
fn();
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,15 @@
|
||||||
package cgotest
|
package cgotest
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
#include <stdint.h>
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
#cgo linux LDFLAGS: -ldl
|
#cgo linux LDFLAGS: -ldl
|
||||||
|
|
||||||
extern void call4029(void *arg);
|
extern uintptr_t dlopen4029(char*, int);
|
||||||
|
extern uintptr_t dlsym4029(uintptr_t, char*);
|
||||||
|
extern int dlclose4029(uintptr_t);
|
||||||
|
|
||||||
|
extern void call4029(uintptr_t arg);
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
|
|
@ -51,15 +56,15 @@ func test4029(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadThySelf(t *testing.T, symbol string) {
|
func loadThySelf(t *testing.T, symbol string) {
|
||||||
this_process := C.dlopen(nil, C.RTLD_NOW)
|
this_process := C.dlopen4029(nil, C.RTLD_NOW)
|
||||||
if this_process == nil {
|
if this_process == 0 {
|
||||||
t.Error("dlopen:", C.GoString(C.dlerror()))
|
t.Error("dlopen:", C.GoString(C.dlerror()))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer C.dlclose(this_process)
|
defer C.dlclose4029(this_process)
|
||||||
|
|
||||||
symbol_address := C.dlsym(this_process, C.CString(symbol))
|
symbol_address := C.dlsym4029(this_process, C.CString(symbol))
|
||||||
if symbol_address == nil {
|
if symbol_address == 0 {
|
||||||
t.Error("dlsym:", C.GoString(C.dlerror()))
|
t.Error("dlsym:", C.GoString(C.dlerror()))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
TEXT cas<>(SB),NOSPLIT,$0
|
TEXT cas<>(SB),NOSPLIT,$0
|
||||||
MOVW $0xffff0fc0, R15 // R15 is PC
|
MOVW $0xffff0fc0, R15 // R15 is PC
|
||||||
|
|
||||||
TEXT ·RewindAndSetgid(SB),NOSPLIT,$-4-0
|
TEXT ·RewindAndSetgid(SB),NOSPLIT|NOFRAME,$0-0
|
||||||
// Save link register
|
// Save link register
|
||||||
MOVW R14, R4
|
MOVW R14, R4
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
#include "textflag.h"
|
#include "textflag.h"
|
||||||
|
|
||||||
TEXT ·RewindAndSetgid(SB),NOSPLIT,$-8-0
|
TEXT ·RewindAndSetgid(SB),NOSPLIT|NOFRAME,$0-0
|
||||||
// Save link register
|
// Save link register
|
||||||
MOVD R30, R9
|
MOVD R30, R9
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
#include "textflag.h"
|
#include "textflag.h"
|
||||||
|
|
||||||
TEXT ·RewindAndSetgid(SB),NOSPLIT,$-4-0
|
TEXT ·RewindAndSetgid(SB),NOSPLIT|NOFRAME,$0-0
|
||||||
// Rewind stack pointer so anything that happens on the stack
|
// Rewind stack pointer so anything that happens on the stack
|
||||||
// will clobber the test pattern created by the caller
|
// will clobber the test pattern created by the caller
|
||||||
ADDU $(1024*8), R29
|
ADDU $(1024*8), R29
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ func IntoGoAndBack() {
|
||||||
|
|
||||||
func testSigprocmask(t *testing.T) {
|
func testSigprocmask(t *testing.T) {
|
||||||
if r := C.RunSigThread(); r != 0 {
|
if r := C.RunSigThread(); r != 0 {
|
||||||
t.Error("pthread_create/pthread_join failed")
|
t.Errorf("pthread_create/pthread_join failed: %d", r)
|
||||||
}
|
}
|
||||||
if !blocked {
|
if !blocked {
|
||||||
t.Error("Go runtime unblocked SIGIO")
|
t.Error("Go runtime unblocked SIGIO")
|
||||||
|
|
|
||||||
74
misc/cgo/test/test22906.go
Normal file
74
misc/cgo/test/test22906.go
Normal file
|
|
@ -0,0 +1,74 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build cgo
|
||||||
|
|
||||||
|
package cgotest
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
// It's going to be hard to include a whole real JVM to test this.
|
||||||
|
// So we'll simulate a really easy JVM using just the parts we need.
|
||||||
|
|
||||||
|
// This is the relevant part of jni.h.
|
||||||
|
|
||||||
|
struct _jobject;
|
||||||
|
|
||||||
|
typedef struct _jobject *jobject;
|
||||||
|
typedef jobject jclass;
|
||||||
|
typedef jobject jthrowable;
|
||||||
|
typedef jobject jstring;
|
||||||
|
typedef jobject jarray;
|
||||||
|
typedef jarray jbooleanArray;
|
||||||
|
typedef jarray jbyteArray;
|
||||||
|
typedef jarray jcharArray;
|
||||||
|
typedef jarray jshortArray;
|
||||||
|
typedef jarray jintArray;
|
||||||
|
typedef jarray jlongArray;
|
||||||
|
typedef jarray jfloatArray;
|
||||||
|
typedef jarray jdoubleArray;
|
||||||
|
typedef jarray jobjectArray;
|
||||||
|
|
||||||
|
typedef jobject jweak;
|
||||||
|
|
||||||
|
// Note: jvalue is already a non-pointer type due to it being a C union.
|
||||||
|
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func test22906(t *testing.T) {
|
||||||
|
var x1 C.jobject = 0 // Note: 0, not nil. That makes sure we use uintptr for these types.
|
||||||
|
_ = x1
|
||||||
|
var x2 C.jclass = 0
|
||||||
|
_ = x2
|
||||||
|
var x3 C.jthrowable = 0
|
||||||
|
_ = x3
|
||||||
|
var x4 C.jstring = 0
|
||||||
|
_ = x4
|
||||||
|
var x5 C.jarray = 0
|
||||||
|
_ = x5
|
||||||
|
var x6 C.jbooleanArray = 0
|
||||||
|
_ = x6
|
||||||
|
var x7 C.jbyteArray = 0
|
||||||
|
_ = x7
|
||||||
|
var x8 C.jcharArray = 0
|
||||||
|
_ = x8
|
||||||
|
var x9 C.jshortArray = 0
|
||||||
|
_ = x9
|
||||||
|
var x10 C.jintArray = 0
|
||||||
|
_ = x10
|
||||||
|
var x11 C.jlongArray = 0
|
||||||
|
_ = x11
|
||||||
|
var x12 C.jfloatArray = 0
|
||||||
|
_ = x12
|
||||||
|
var x13 C.jdoubleArray = 0
|
||||||
|
_ = x13
|
||||||
|
var x14 C.jobjectArray = 0
|
||||||
|
_ = x14
|
||||||
|
var x15 C.jweak = 0
|
||||||
|
_ = x15
|
||||||
|
}
|
||||||
|
|
@ -13,6 +13,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
@ -166,6 +167,28 @@ func testInstall(t *testing.T, exe, libgoa, libgoh string, buildcmd ...string) {
|
||||||
t.Logf("%s", out)
|
t.Logf("%s", out)
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkLineComments(t, libgoh)
|
||||||
|
}
|
||||||
|
|
||||||
|
var badLineRegexp = regexp.MustCompile(`(?m)^#line [0-9]+ "/.*$`)
|
||||||
|
|
||||||
|
// checkLineComments checks that the export header generated by
|
||||||
|
// -buildmode=c-archive doesn't have any absolute paths in the #line
|
||||||
|
// comments. We don't want those paths because they are unhelpful for
|
||||||
|
// the user and make the files change based on details of the location
|
||||||
|
// of GOPATH.
|
||||||
|
func checkLineComments(t *testing.T, hdrname string) {
|
||||||
|
hdr, err := ioutil.ReadFile(hdrname)
|
||||||
|
if err != nil {
|
||||||
|
if !os.IsNotExist(err) {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if line := badLineRegexp.Find(hdr); line != nil {
|
||||||
|
t.Errorf("bad #line directive with absolute path in %s: %q", hdrname, line)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInstall(t *testing.T) {
|
func TestInstall(t *testing.T) {
|
||||||
|
|
@ -209,6 +232,7 @@ func TestEarlySignalHandler(t *testing.T) {
|
||||||
t.Logf("%s", out)
|
t.Logf("%s", out)
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
checkLineComments(t, "libgo2.h")
|
||||||
|
|
||||||
ccArgs := append(cc, "-o", "testp"+exeSuffix, "main2.c", "libgo2.a")
|
ccArgs := append(cc, "-o", "testp"+exeSuffix, "main2.c", "libgo2.a")
|
||||||
if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
|
if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
|
||||||
|
|
@ -238,6 +262,7 @@ func TestSignalForwarding(t *testing.T) {
|
||||||
t.Logf("%s", out)
|
t.Logf("%s", out)
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
checkLineComments(t, "libgo2.h")
|
||||||
|
|
||||||
ccArgs := append(cc, "-o", "testp"+exeSuffix, "main5.c", "libgo2.a")
|
ccArgs := append(cc, "-o", "testp"+exeSuffix, "main5.c", "libgo2.a")
|
||||||
if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
|
if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
|
||||||
|
|
@ -260,6 +285,9 @@ func TestSignalForwarding(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSignalForwardingExternal(t *testing.T) {
|
func TestSignalForwardingExternal(t *testing.T) {
|
||||||
|
if GOOS == "freebsd" {
|
||||||
|
t.Skipf("skipping on %s/%s; signal always goes to the Go runtime", GOOS, GOARCH)
|
||||||
|
}
|
||||||
checkSignalForwardingTest(t)
|
checkSignalForwardingTest(t)
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
|
|
@ -275,6 +303,7 @@ func TestSignalForwardingExternal(t *testing.T) {
|
||||||
t.Logf("%s", out)
|
t.Logf("%s", out)
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
checkLineComments(t, "libgo2.h")
|
||||||
|
|
||||||
ccArgs := append(cc, "-o", "testp"+exeSuffix, "main5.c", "libgo2.a")
|
ccArgs := append(cc, "-o", "testp"+exeSuffix, "main5.c", "libgo2.a")
|
||||||
if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
|
if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
|
||||||
|
|
@ -387,6 +416,7 @@ func TestOsSignal(t *testing.T) {
|
||||||
t.Logf("%s", out)
|
t.Logf("%s", out)
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
checkLineComments(t, "libgo3.h")
|
||||||
|
|
||||||
ccArgs := append(cc, "-o", "testp"+exeSuffix, "main3.c", "libgo3.a")
|
ccArgs := append(cc, "-o", "testp"+exeSuffix, "main3.c", "libgo3.a")
|
||||||
if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
|
if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
|
||||||
|
|
@ -419,6 +449,7 @@ func TestSigaltstack(t *testing.T) {
|
||||||
t.Logf("%s", out)
|
t.Logf("%s", out)
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
checkLineComments(t, "libgo4.h")
|
||||||
|
|
||||||
ccArgs := append(cc, "-o", "testp"+exeSuffix, "main4.c", "libgo4.a")
|
ccArgs := append(cc, "-o", "testp"+exeSuffix, "main4.c", "libgo4.a")
|
||||||
if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
|
if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
|
||||||
|
|
@ -433,7 +464,7 @@ func TestSigaltstack(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const testar = `#!/usr/bin/env bash
|
const testar = `#!/usr/bin/env bash
|
||||||
while expr $1 : '[-]' >/dev/null; do
|
while [[ $1 == -* ]] >/dev/null; do
|
||||||
shift
|
shift
|
||||||
done
|
done
|
||||||
echo "testar" > $1
|
echo "testar" > $1
|
||||||
|
|
@ -470,6 +501,7 @@ func TestExtar(t *testing.T) {
|
||||||
t.Logf("%s", out)
|
t.Logf("%s", out)
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
checkLineComments(t, "libgo4.h")
|
||||||
|
|
||||||
if _, err := os.Stat("testar.ran"); err != nil {
|
if _, err := os.Stat("testar.ran"); err != nil {
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
|
|
@ -570,6 +602,7 @@ func TestSIGPROF(t *testing.T) {
|
||||||
t.Logf("%s", out)
|
t.Logf("%s", out)
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
checkLineComments(t, "libgo6.h")
|
||||||
|
|
||||||
ccArgs := append(cc, "-o", "testp6"+exeSuffix, "main6.c", "libgo6.a")
|
ccArgs := append(cc, "-o", "testp6"+exeSuffix, "main6.c", "libgo6.a")
|
||||||
if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
|
if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
|
||||||
|
|
@ -608,6 +641,7 @@ func TestCompileWithoutShared(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
checkLineComments(t, "libgo2.h")
|
||||||
|
|
||||||
exe := "./testnoshared" + exeSuffix
|
exe := "./testnoshared" + exeSuffix
|
||||||
|
|
||||||
|
|
@ -642,3 +676,50 @@ func TestCompileWithoutShared(t *testing.T) {
|
||||||
t.Logf("%s", out)
|
t.Logf("%s", out)
|
||||||
expectSignal(t, err, syscall.SIGPIPE)
|
expectSignal(t, err, syscall.SIGPIPE)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test that installing a second time recreates the header files.
|
||||||
|
func TestCachedInstall(t *testing.T) {
|
||||||
|
defer os.RemoveAll("pkg")
|
||||||
|
|
||||||
|
h1 := filepath.Join("pkg", libgodir, "libgo.h")
|
||||||
|
h2 := filepath.Join("pkg", libgodir, "p.h")
|
||||||
|
|
||||||
|
buildcmd := []string{"go", "install", "-i", "-buildmode=c-archive", "libgo"}
|
||||||
|
|
||||||
|
cmd := exec.Command(buildcmd[0], buildcmd[1:]...)
|
||||||
|
cmd.Env = gopathEnv
|
||||||
|
t.Log(buildcmd)
|
||||||
|
if out, err := cmd.CombinedOutput(); err != nil {
|
||||||
|
t.Logf("%s", out)
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := os.Stat(h1); err != nil {
|
||||||
|
t.Errorf("libgo.h not installed: %v", err)
|
||||||
|
}
|
||||||
|
if _, err := os.Stat(h2); err != nil {
|
||||||
|
t.Errorf("p.h not installed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := os.Remove(h1); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := os.Remove(h2); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd = exec.Command(buildcmd[0], buildcmd[1:]...)
|
||||||
|
cmd.Env = gopathEnv
|
||||||
|
t.Log(buildcmd)
|
||||||
|
if out, err := cmd.CombinedOutput(); err != nil {
|
||||||
|
t.Logf("%s", out)
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := os.Stat(h1); err != nil {
|
||||||
|
t.Errorf("libgo.h not installed in second run: %v", err)
|
||||||
|
}
|
||||||
|
if _, err := os.Stat(h2); err != nil {
|
||||||
|
t.Errorf("p.h not installed in second run: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,8 @@ int main(int argc, char** argv) {
|
||||||
printf("write(2) unexpectedly succeeded\n");
|
printf("write(2) unexpectedly succeeded\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
printf("did not receieve SIGPIPE\n");
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
printf("Unknown test: %d\n", test);
|
printf("Unknown test: %d\n", test);
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ package cshared_test
|
||||||
import (
|
import (
|
||||||
"debug/elf"
|
"debug/elf"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
|
@ -55,7 +56,8 @@ func TestMain(m *testing.M) {
|
||||||
|
|
||||||
androiddir = fmt.Sprintf("/data/local/tmp/testcshared-%d", os.Getpid())
|
androiddir = fmt.Sprintf("/data/local/tmp/testcshared-%d", os.Getpid())
|
||||||
if GOOS == "android" {
|
if GOOS == "android" {
|
||||||
cmd := exec.Command("adb", "shell", "mkdir", "-p", androiddir)
|
args := append(adbCmd(), "shell", "mkdir", "-p", androiddir)
|
||||||
|
cmd := exec.Command(args[0], args[1:]...)
|
||||||
out, err := cmd.CombinedOutput()
|
out, err := cmd.CombinedOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("setupAndroid failed: %v\n%s\n", err, out)
|
log.Fatalf("setupAndroid failed: %v\n%s\n", err, out)
|
||||||
|
|
@ -154,11 +156,19 @@ func cmdToRun(name string) string {
|
||||||
return "./" + name + exeSuffix
|
return "./" + name + exeSuffix
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func adbCmd() []string {
|
||||||
|
cmd := []string{"adb"}
|
||||||
|
if flags := os.Getenv("GOANDROID_ADB_FLAGS"); flags != "" {
|
||||||
|
cmd = append(cmd, strings.Split(flags, " ")...)
|
||||||
|
}
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
func adbPush(t *testing.T, filename string) {
|
func adbPush(t *testing.T, filename string) {
|
||||||
if GOOS != "android" {
|
if GOOS != "android" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
args := []string{"adb", "push", filename, fmt.Sprintf("%s/%s", androiddir, filename)}
|
args := append(adbCmd(), "push", filename, fmt.Sprintf("%s/%s", androiddir, filename))
|
||||||
cmd := exec.Command(args[0], args[1:]...)
|
cmd := exec.Command(args[0], args[1:]...)
|
||||||
if out, err := cmd.CombinedOutput(); err != nil {
|
if out, err := cmd.CombinedOutput(); err != nil {
|
||||||
t.Fatalf("adb command failed: %v\n%s\n", err, out)
|
t.Fatalf("adb command failed: %v\n%s\n", err, out)
|
||||||
|
|
@ -169,7 +179,7 @@ func adbRun(t *testing.T, env []string, adbargs ...string) string {
|
||||||
if GOOS != "android" {
|
if GOOS != "android" {
|
||||||
t.Fatalf("trying to run adb command when operating system is not android.")
|
t.Fatalf("trying to run adb command when operating system is not android.")
|
||||||
}
|
}
|
||||||
args := []string{"adb", "shell"}
|
args := append(adbCmd(), "shell")
|
||||||
// Propagate LD_LIBRARY_PATH to the adb shell invocation.
|
// Propagate LD_LIBRARY_PATH to the adb shell invocation.
|
||||||
for _, e := range env {
|
for _, e := range env {
|
||||||
if strings.Index(e, "LD_LIBRARY_PATH=") != -1 {
|
if strings.Index(e, "LD_LIBRARY_PATH=") != -1 {
|
||||||
|
|
@ -237,7 +247,7 @@ func createHeaders() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if GOOS == "android" {
|
if GOOS == "android" {
|
||||||
args = []string{"adb", "push", libgoname, fmt.Sprintf("%s/%s", androiddir, libgoname)}
|
args = append(adbCmd(), "push", libgoname, fmt.Sprintf("%s/%s", androiddir, libgoname))
|
||||||
cmd = exec.Command(args[0], args[1:]...)
|
cmd = exec.Command(args[0], args[1:]...)
|
||||||
out, err = cmd.CombinedOutput()
|
out, err = cmd.CombinedOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -270,7 +280,8 @@ func cleanupAndroid() {
|
||||||
if GOOS != "android" {
|
if GOOS != "android" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
cmd := exec.Command("adb", "shell", "rm", "-rf", androiddir)
|
args := append(adbCmd(), "shell", "rm", "-rf", androiddir)
|
||||||
|
cmd := exec.Command(args[0], args[1:]...)
|
||||||
out, err := cmd.CombinedOutput()
|
out, err := cmd.CombinedOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("cleanupAndroid failed: %v\n%s\n", err, out)
|
log.Fatalf("cleanupAndroid failed: %v\n%s\n", err, out)
|
||||||
|
|
@ -311,7 +322,11 @@ func TestExportedSymbolsWithDynamicLoad(t *testing.T) {
|
||||||
|
|
||||||
createHeadersOnce(t)
|
createHeadersOnce(t)
|
||||||
|
|
||||||
runCC(t, "-o", cmd, "main1.c", "-ldl")
|
if GOOS != "freebsd" {
|
||||||
|
runCC(t, "-o", cmd, "main1.c", "-ldl")
|
||||||
|
} else {
|
||||||
|
runCC(t, "-o", cmd, "main1.c")
|
||||||
|
}
|
||||||
adbPush(t, cmd)
|
adbPush(t, cmd)
|
||||||
|
|
||||||
defer os.Remove(bin)
|
defer os.Remove(bin)
|
||||||
|
|
@ -400,7 +415,11 @@ func testSignalHandlers(t *testing.T, pkgname, cfile, cmd string) {
|
||||||
"-o", libname, pkgname,
|
"-o", libname, pkgname,
|
||||||
)
|
)
|
||||||
adbPush(t, libname)
|
adbPush(t, libname)
|
||||||
runCC(t, "-pthread", "-o", cmd, cfile, "-ldl")
|
if GOOS != "freebsd" {
|
||||||
|
runCC(t, "-pthread", "-o", cmd, cfile, "-ldl")
|
||||||
|
} else {
|
||||||
|
runCC(t, "-pthread", "-o", cmd, cfile)
|
||||||
|
}
|
||||||
adbPush(t, cmd)
|
adbPush(t, cmd)
|
||||||
|
|
||||||
bin := cmdToRun(cmd)
|
bin := cmdToRun(cmd)
|
||||||
|
|
@ -477,3 +496,99 @@ func TestPIE(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test that installing a second time recreates the header files.
|
||||||
|
func TestCachedInstall(t *testing.T) {
|
||||||
|
tmpdir, err := ioutil.TempDir("", "cshared")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
// defer os.RemoveAll(tmpdir)
|
||||||
|
|
||||||
|
copyFile(t, filepath.Join(tmpdir, "src", "libgo", "libgo.go"), filepath.Join("src", "libgo", "libgo.go"))
|
||||||
|
copyFile(t, filepath.Join(tmpdir, "src", "p", "p.go"), filepath.Join("src", "p", "p.go"))
|
||||||
|
|
||||||
|
env := append(os.Environ(), "GOPATH="+tmpdir)
|
||||||
|
|
||||||
|
buildcmd := []string{"go", "install", "-x", "-i", "-buildmode=c-shared", "-installsuffix", "testcshared", "libgo"}
|
||||||
|
|
||||||
|
cmd := exec.Command(buildcmd[0], buildcmd[1:]...)
|
||||||
|
cmd.Env = env
|
||||||
|
t.Log(buildcmd)
|
||||||
|
out, err := cmd.CombinedOutput()
|
||||||
|
t.Logf("%s", out)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var libgoh, ph string
|
||||||
|
|
||||||
|
walker := func(path string, info os.FileInfo, err error) error {
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
var ps *string
|
||||||
|
switch filepath.Base(path) {
|
||||||
|
case "libgo.h":
|
||||||
|
ps = &libgoh
|
||||||
|
case "p.h":
|
||||||
|
ps = &ph
|
||||||
|
}
|
||||||
|
if ps != nil {
|
||||||
|
if *ps != "" {
|
||||||
|
t.Fatalf("%s found again", *ps)
|
||||||
|
}
|
||||||
|
*ps = path
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := filepath.Walk(tmpdir, walker); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if libgoh == "" {
|
||||||
|
t.Fatal("libgo.h not installed")
|
||||||
|
}
|
||||||
|
if ph == "" {
|
||||||
|
t.Fatal("p.h not installed")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := os.Remove(libgoh); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := os.Remove(ph); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd = exec.Command(buildcmd[0], buildcmd[1:]...)
|
||||||
|
cmd.Env = env
|
||||||
|
t.Log(buildcmd)
|
||||||
|
out, err = cmd.CombinedOutput()
|
||||||
|
t.Logf("%s", out)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := os.Stat(libgoh); err != nil {
|
||||||
|
t.Errorf("libgo.h not installed in second run: %v", err)
|
||||||
|
}
|
||||||
|
if _, err := os.Stat(ph); err != nil {
|
||||||
|
t.Errorf("p.h not installed in second run: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// copyFile copies src to dst.
|
||||||
|
func copyFile(t *testing.T, dst, src string) {
|
||||||
|
t.Helper()
|
||||||
|
data, err := ioutil.ReadFile(src)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := os.MkdirAll(filepath.Dir(dst), 0777); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := ioutil.WriteFile(dst, data, 0666); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#define fd (100)
|
#define fd (30)
|
||||||
|
|
||||||
// Tests libgo2.so, which does not export any functions.
|
// Tests libgo2.so, which does not export any functions.
|
||||||
// Read a string from the file descriptor and print it.
|
// Read a string from the file descriptor and print it.
|
||||||
|
|
@ -21,7 +21,7 @@ int main(void) {
|
||||||
|
|
||||||
// The descriptor will be initialized in a thread, so we have to
|
// The descriptor will be initialized in a thread, so we have to
|
||||||
// give a chance to get opened.
|
// give a chance to get opened.
|
||||||
for (i = 0; i < 1000; i++) {
|
for (i = 0; i < 200; i++) {
|
||||||
n = read(fd, buf, sizeof buf);
|
n = read(fd, buf, sizeof buf);
|
||||||
if (n >= 0)
|
if (n >= 0)
|
||||||
break;
|
break;
|
||||||
|
|
@ -33,7 +33,7 @@ int main(void) {
|
||||||
// An EBADF error means that the shared library has not opened the
|
// An EBADF error means that the shared library has not opened the
|
||||||
// descriptor yet.
|
// descriptor yet.
|
||||||
ts.tv_sec = 0;
|
ts.tv_sec = 0;
|
||||||
ts.tv_nsec = 1000000;
|
ts.tv_nsec = 10000000;
|
||||||
nanosleep(&ts, NULL);
|
nanosleep(&ts, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ import (
|
||||||
// that the C code can also use.
|
// that the C code can also use.
|
||||||
|
|
||||||
const (
|
const (
|
||||||
fd = 100
|
fd = 30
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
|
|
||||||
21
misc/cgo/testplugin/src/issue24351/main.go
Normal file
21
misc/cgo/testplugin/src/issue24351/main.go
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
// Copyright 2018 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 main
|
||||||
|
|
||||||
|
import "plugin"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
p, err := plugin.Open("issue24351.so")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
f, err := p.Lookup("B")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
c := make(chan bool)
|
||||||
|
f.(func(chan bool))(c)
|
||||||
|
<-c
|
||||||
|
}
|
||||||
14
misc/cgo/testplugin/src/issue24351/plugin.go
Normal file
14
misc/cgo/testplugin/src/issue24351/plugin.go
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
// Copyright 2018 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 main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func B(c chan bool) {
|
||||||
|
go func() {
|
||||||
|
fmt.Println(1.5)
|
||||||
|
c <- true
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
@ -85,3 +85,8 @@ GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -o issue22175 src/issue22175/main.
|
||||||
GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -o issue.22295.so issue22295.pkg
|
GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -o issue.22295.so issue22295.pkg
|
||||||
GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -o issue22295 src/issue22295.pkg/main.go
|
GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -o issue22295 src/issue22295.pkg/main.go
|
||||||
./issue22295
|
./issue22295
|
||||||
|
|
||||||
|
# Test for issue 24351
|
||||||
|
GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -o issue24351.so src/issue24351/plugin.go
|
||||||
|
GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -o issue24351 src/issue24351/main.go
|
||||||
|
./issue24351
|
||||||
|
|
|
||||||
|
|
@ -407,7 +407,7 @@ func (d *tempDir) RemoveAll(t *testing.T) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err := os.RemoveAll(d.base); err != nil {
|
if err := os.RemoveAll(d.base); err != nil {
|
||||||
t.Fatal("Failed to remove temp dir: %v", err)
|
t.Fatalf("Failed to remove temp dir: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -351,10 +351,10 @@ func readNotes(f *elf.File) ([]*note, error) {
|
||||||
|
|
||||||
func dynStrings(t *testing.T, path string, flag elf.DynTag) []string {
|
func dynStrings(t *testing.T, path string, flag elf.DynTag) []string {
|
||||||
f, err := elf.Open(path)
|
f, err := elf.Open(path)
|
||||||
defer f.Close()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("elf.Open(%q) failed: %v", path, err)
|
t.Fatalf("elf.Open(%q) failed: %v", path, err)
|
||||||
}
|
}
|
||||||
|
defer f.Close()
|
||||||
dynstrings, err := f.DynString(flag)
|
dynstrings, err := f.DynString(flag)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("DynString(%s) failed on %s: %v", flag, path, err)
|
t.Fatalf("DynString(%s) failed on %s: %v", flag, path, err)
|
||||||
|
|
@ -598,7 +598,6 @@ func TestThreeGopathShlibs(t *testing.T) {
|
||||||
// If gccgo is not available or not new enough call t.Skip. Otherwise,
|
// If gccgo is not available or not new enough call t.Skip. Otherwise,
|
||||||
// return a build.Context that is set up for gccgo.
|
// return a build.Context that is set up for gccgo.
|
||||||
func prepGccgo(t *testing.T) build.Context {
|
func prepGccgo(t *testing.T) build.Context {
|
||||||
t.Skip("golang.org/issue/22472")
|
|
||||||
gccgoName := os.Getenv("GCCGO")
|
gccgoName := os.Getenv("GCCGO")
|
||||||
if gccgoName == "" {
|
if gccgoName == "" {
|
||||||
gccgoName = "gccgo"
|
gccgoName = "gccgo"
|
||||||
|
|
@ -648,8 +647,6 @@ func TestGoPathShlibGccgo(t *testing.T) {
|
||||||
// library with gccgo, another GOPATH package that depends on the first and an
|
// library with gccgo, another GOPATH package that depends on the first and an
|
||||||
// executable that links the second library.
|
// executable that links the second library.
|
||||||
func TestTwoGopathShlibsGccgo(t *testing.T) {
|
func TestTwoGopathShlibsGccgo(t *testing.T) {
|
||||||
t.Skip("golang.org/issue/22224")
|
|
||||||
|
|
||||||
gccgoContext := prepGccgo(t)
|
gccgoContext := prepGccgo(t)
|
||||||
|
|
||||||
libgoRE := regexp.MustCompile("libgo.so.[0-9]+")
|
libgoRE := regexp.MustCompile("libgo.so.[0-9]+")
|
||||||
|
|
@ -793,6 +790,7 @@ func TestRebuilding(t *testing.T) {
|
||||||
// If the .a file is newer than the .so, the .so is rebuilt (but not the .a)
|
// If the .a file is newer than the .so, the .so is rebuilt (but not the .a)
|
||||||
t.Run("newarchive", func(t *testing.T) {
|
t.Run("newarchive", func(t *testing.T) {
|
||||||
resetFileStamps()
|
resetFileStamps()
|
||||||
|
AssertNotRebuilt(t, "new .a file before build", filepath.Join(gopathInstallDir, "depBase.a"))
|
||||||
goCmd(t, "list", "-linkshared", "-f={{.ImportPath}} {{.Stale}} {{.StaleReason}} {{.Target}}", "depBase")
|
goCmd(t, "list", "-linkshared", "-f={{.ImportPath}} {{.Stale}} {{.StaleReason}} {{.Target}}", "depBase")
|
||||||
AssertNotRebuilt(t, "new .a file before build", filepath.Join(gopathInstallDir, "depBase.a"))
|
AssertNotRebuilt(t, "new .a file before build", filepath.Join(gopathInstallDir, "depBase.a"))
|
||||||
cleanup := touch(t, filepath.Join(gopathInstallDir, "depBase.a"))
|
cleanup := touch(t, filepath.Join(gopathInstallDir, "depBase.a"))
|
||||||
|
|
|
||||||
|
|
@ -1,44 +1,50 @@
|
||||||
Go on iOS
|
Go on iOS
|
||||||
=========
|
=========
|
||||||
|
|
||||||
To build a cross compiling toolchain for iOS on OS X, first modify clangwrap.sh
|
For details on developing Go for iOS on macOS, see the documentation in the mobile
|
||||||
in misc/ios to match your setup. And then run:
|
subrepository:
|
||||||
|
|
||||||
GOARM=7 CGO_ENABLED=1 GOARCH=arm CC_FOR_TARGET=`pwd`/../misc/ios/clangwrap.sh \
|
https://github.com/golang/mobile
|
||||||
CXX_FOR_TARGET=`pwd`/../misc/ios/clangwrap.sh ./make.bash
|
|
||||||
|
|
||||||
To build a program, use the normal go build command:
|
It is necessary to set up the environment before running tests or programs directly on a
|
||||||
|
device.
|
||||||
|
|
||||||
CGO_ENABLED=1 GOARCH=arm go build import/path
|
First make sure you have a valid developer certificate and have setup your device properly
|
||||||
|
to run apps signed by your developer certificate. Then install the libimobiledevice and
|
||||||
|
ideviceinstaller tools from https://www.libimobiledevice.org/. Use the HEAD versions from
|
||||||
|
source; the stable versions have bugs that prevents the Go exec wrapper to install and run
|
||||||
|
apps.
|
||||||
|
|
||||||
To run a program on an iDevice, first make sure you have a valid developer
|
Second, the Go exec wrapper must be told the developer account signing identity, the team
|
||||||
certificate and have setup your iDevice properly to run apps signed by your
|
id and a provisioned bundle id to use. They're specified with the environment variables
|
||||||
developer certificate. Then install https://github.com/phonegap/ios-deploy.
|
GOIOS_DEV_ID, GOIOS_TEAM_ID and GOIOS_APP_ID. The detect.go program in this directory will
|
||||||
At a first step, you can try building the famous hello world program to run
|
attempt to auto-detect suitable values. Run it as
|
||||||
on your test device.
|
|
||||||
(The needed files are provided at https://github.com/minux/go-ios-examples.)
|
|
||||||
|
|
||||||
# assume your program binary is helloworld.go, build it into the
|
go run detect.go
|
||||||
# example hello.app bundle.
|
|
||||||
CGO_ENABLED=1 GOARCH=arm go build -o hello.app/hello helloworld.go
|
|
||||||
# sign the executable using your developer certificate
|
|
||||||
codesign -f -s "iPhone Developer" --entitlements hello.app/Entitlements.plist hello.app/hello
|
|
||||||
# run the program inside lldb on iDevice, run `ios-deploy` for more
|
|
||||||
# command options
|
|
||||||
ios-deploy --debug --uninstall --bundle hello.app
|
|
||||||
# Depending on your ios-deploy version, you might need to enter "run"
|
|
||||||
# into lldb to run your program, and its output will be shown by lldb.
|
|
||||||
|
|
||||||
Notes:
|
which will output something similar to
|
||||||
- A dummy hello.app bundle is provided in this directory to help you get started.
|
|
||||||
- Running the program on an iDevice requires code sign and thus external linking,
|
|
||||||
if your program uses cgo, then it will automatically use external linking.
|
|
||||||
However, if your program does not use cgo, please make sure to add
|
|
||||||
import _ "runtime/cgo"
|
|
||||||
so that external linking will be used.
|
|
||||||
|
|
||||||
Known issues
|
export GOIOS_DEV_ID="iPhone Developer: xxx@yyy.zzz (XXXXXXXX)"
|
||||||
============
|
export GOIOS_APP_ID=YYYYYYYY.some.bundle.id
|
||||||
- crypto/x509 won't build, I don't yet know how to get system root on iOS.
|
export GOIOS_TEAM_ID=ZZZZZZZZ
|
||||||
- Because I still want to be able to do native build, CGO_ENABLED=1 is not the
|
|
||||||
default, yet.
|
If you have multiple devices connected, specify the device UDID with the GOIOS_DEVICE_ID
|
||||||
|
variable. Use `idevice_id -l` to list all available UDIDs.
|
||||||
|
|
||||||
|
Finally, to run the standard library tests, run iostest.bash with GOARCH set. For example,
|
||||||
|
|
||||||
|
GOARCH=arm64 ./iostest.bash
|
||||||
|
|
||||||
|
To use the go tool directly to run programs and tests, put $GOROOT/bin into PATH to ensure
|
||||||
|
the go_darwin_$GOARCH_exec wrapper is found. For example, to run the archive/tar tests
|
||||||
|
|
||||||
|
export PATH=$GOROOT/bin:$PATH
|
||||||
|
GOARCH=arm64 go test archive/tar
|
||||||
|
|
||||||
|
Note that the go_darwin_$GOARCH_exec wrapper uninstalls any existing app identified by
|
||||||
|
the bundle id before installing a new app. If the uninstalled app is the last app by
|
||||||
|
the developer identity, the device might also remove the permission to run apps from
|
||||||
|
that developer, and the exec wrapper will fail to install the new app. To avoid that,
|
||||||
|
install another app with the same developer identity but with a different bundle id.
|
||||||
|
That way, the permission to install apps is held on to while the primary app is
|
||||||
|
uninstalled.
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"crypto/x509"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
|
@ -22,12 +23,14 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
devID := detectDevID()
|
udids := getLines(exec.Command("idevice_id", "-l"))
|
||||||
|
if len(udids) == 0 {
|
||||||
|
fail("no udid found; is a device connected?")
|
||||||
|
}
|
||||||
|
|
||||||
udid := detectUDID()
|
mps := detectMobileProvisionFiles(udids)
|
||||||
mps := detectMobileProvisionFiles(udid)
|
|
||||||
if len(mps) == 0 {
|
if len(mps) == 0 {
|
||||||
fail("did not find mobile provision matching device udid %s", udid)
|
fail("did not find mobile provision matching device udids %q", udids)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("Available provisioning profiles below.")
|
fmt.Println("Available provisioning profiles below.")
|
||||||
|
|
@ -35,7 +38,6 @@ func main() {
|
||||||
fmt.Println("will be overwritten when running Go programs.")
|
fmt.Println("will be overwritten when running Go programs.")
|
||||||
for _, mp := range mps {
|
for _, mp := range mps {
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Printf("export GOIOS_DEV_ID=%s\n", devID)
|
|
||||||
f, err := ioutil.TempFile("", "go_ios_detect_")
|
f, err := ioutil.TempFile("", "go_ios_detect_")
|
||||||
check(err)
|
check(err)
|
||||||
fname := f.Name()
|
fname := f.Name()
|
||||||
|
|
@ -46,6 +48,12 @@ func main() {
|
||||||
check(err)
|
check(err)
|
||||||
check(f.Close())
|
check(f.Close())
|
||||||
|
|
||||||
|
cert, err := plistExtract(fname, "DeveloperCertificates:0")
|
||||||
|
check(err)
|
||||||
|
pcert, err := x509.ParseCertificate(cert)
|
||||||
|
check(err)
|
||||||
|
fmt.Printf("export GOIOS_DEV_ID=\"%s\"\n", pcert.Subject.CommonName)
|
||||||
|
|
||||||
appID, err := plistExtract(fname, "Entitlements:application-identifier")
|
appID, err := plistExtract(fname, "Entitlements:application-identifier")
|
||||||
check(err)
|
check(err)
|
||||||
fmt.Printf("export GOIOS_APP_ID=%s\n", appID)
|
fmt.Printf("export GOIOS_APP_ID=%s\n", appID)
|
||||||
|
|
@ -56,39 +64,7 @@ func main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func detectDevID() string {
|
func detectMobileProvisionFiles(udids [][]byte) []string {
|
||||||
cmd := exec.Command("security", "find-identity", "-p", "codesigning", "-v")
|
|
||||||
lines := getLines(cmd)
|
|
||||||
|
|
||||||
for _, line := range lines {
|
|
||||||
if !bytes.Contains(line, []byte("iPhone Developer")) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if bytes.Contains(line, []byte("REVOKED")) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
fields := bytes.Fields(line)
|
|
||||||
return string(fields[1])
|
|
||||||
}
|
|
||||||
fail("no code signing identity found")
|
|
||||||
panic("unreachable")
|
|
||||||
}
|
|
||||||
|
|
||||||
var udidPrefix = []byte("UniqueDeviceID: ")
|
|
||||||
|
|
||||||
func detectUDID() []byte {
|
|
||||||
cmd := exec.Command("ideviceinfo")
|
|
||||||
lines := getLines(cmd)
|
|
||||||
for _, line := range lines {
|
|
||||||
if bytes.HasPrefix(line, udidPrefix) {
|
|
||||||
return bytes.TrimPrefix(line, udidPrefix)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fail("udid not found; is the device connected?")
|
|
||||||
panic("unreachable")
|
|
||||||
}
|
|
||||||
|
|
||||||
func detectMobileProvisionFiles(udid []byte) []string {
|
|
||||||
cmd := exec.Command("mdfind", "-name", ".mobileprovision")
|
cmd := exec.Command("mdfind", "-name", ".mobileprovision")
|
||||||
lines := getLines(cmd)
|
lines := getLines(cmd)
|
||||||
|
|
||||||
|
|
@ -98,11 +74,17 @@ func detectMobileProvisionFiles(udid []byte) []string {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
xmlLines := getLines(parseMobileProvision(string(line)))
|
xmlLines := getLines(parseMobileProvision(string(line)))
|
||||||
for _, xmlLine := range xmlLines {
|
matches := 0
|
||||||
if bytes.Contains(xmlLine, udid) {
|
for _, udid := range udids {
|
||||||
files = append(files, string(line))
|
for _, xmlLine := range xmlLines {
|
||||||
|
if bytes.Contains(xmlLine, udid) {
|
||||||
|
matches++
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if matches == len(udids) {
|
||||||
|
files = append(files, string(line))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return files
|
return files
|
||||||
}
|
}
|
||||||
|
|
@ -121,7 +103,12 @@ func plistExtract(fname string, path string) ([]byte, error) {
|
||||||
|
|
||||||
func getLines(cmd *exec.Cmd) [][]byte {
|
func getLines(cmd *exec.Cmd) [][]byte {
|
||||||
out := output(cmd)
|
out := output(cmd)
|
||||||
return bytes.Split(out, []byte("\n"))
|
lines := bytes.Split(out, []byte("\n"))
|
||||||
|
// Skip the empty line at the end.
|
||||||
|
if len(lines[len(lines)-1]) == 0 {
|
||||||
|
lines = lines[:len(lines)-1]
|
||||||
|
}
|
||||||
|
return lines
|
||||||
}
|
}
|
||||||
|
|
||||||
func output(cmd *exec.Cmd) []byte {
|
func output(cmd *exec.Cmd) []byte {
|
||||||
|
|
|
||||||
|
|
@ -21,27 +21,26 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/xml"
|
||||||
"errors"
|
"errors"
|
||||||
"flag"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/build"
|
"go/build"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"os/signal"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
const debug = false
|
const debug = false
|
||||||
|
|
||||||
var errRetry = errors.New("failed to start test harness (retry attempted)")
|
|
||||||
|
|
||||||
var tmpdir string
|
var tmpdir string
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -88,10 +87,28 @@ func main() {
|
||||||
bundleID = parts[1]
|
bundleID = parts[1]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exitCode, err := runMain()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("%v\n", err)
|
||||||
|
}
|
||||||
|
os.Exit(exitCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
func runMain() (int, error) {
|
||||||
var err error
|
var err error
|
||||||
tmpdir, err = ioutil.TempDir("", "go_darwin_arm_exec_")
|
tmpdir, err = ioutil.TempDir("", "go_darwin_arm_exec_")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
return 1, err
|
||||||
|
}
|
||||||
|
if !debug {
|
||||||
|
defer os.RemoveAll(tmpdir)
|
||||||
|
}
|
||||||
|
|
||||||
|
appdir := filepath.Join(tmpdir, "gotest.app")
|
||||||
|
os.RemoveAll(appdir)
|
||||||
|
|
||||||
|
if err := assembleApp(appdir, os.Args[1]); err != nil {
|
||||||
|
return 1, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// This wrapper uses complicated machinery to run iOS binaries. It
|
// This wrapper uses complicated machinery to run iOS binaries. It
|
||||||
|
|
@ -103,33 +120,43 @@ func main() {
|
||||||
lockName := filepath.Join(os.TempDir(), "go_darwin_arm_exec-"+deviceID+".lock")
|
lockName := filepath.Join(os.TempDir(), "go_darwin_arm_exec-"+deviceID+".lock")
|
||||||
lock, err = os.OpenFile(lockName, os.O_CREATE|os.O_RDONLY, 0666)
|
lock, err = os.OpenFile(lockName, os.O_CREATE|os.O_RDONLY, 0666)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
return 1, err
|
||||||
}
|
}
|
||||||
if err := syscall.Flock(int(lock.Fd()), syscall.LOCK_EX); err != nil {
|
if err := syscall.Flock(int(lock.Fd()), syscall.LOCK_EX); err != nil {
|
||||||
log.Fatal(err)
|
return 1, err
|
||||||
}
|
}
|
||||||
// Approximately 1 in a 100 binaries fail to start. If it happens,
|
|
||||||
// try again. These failures happen for several reasons beyond
|
if err := uninstall(bundleID); err != nil {
|
||||||
// our control, but all of them are safe to retry as they happen
|
return 1, err
|
||||||
// before lldb encounters the initial getwd breakpoint. As we
|
|
||||||
// know the tests haven't started, we are not hiding flaky tests
|
|
||||||
// with this retry.
|
|
||||||
for i := 0; i < 5; i++ {
|
|
||||||
if i > 0 {
|
|
||||||
fmt.Fprintln(os.Stderr, "start timeout, trying again")
|
|
||||||
}
|
|
||||||
err = run(os.Args[1], os.Args[2:])
|
|
||||||
if err == nil || err != errRetry {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if !debug {
|
|
||||||
os.RemoveAll(tmpdir)
|
if err := install(appdir); err != nil {
|
||||||
|
return 1, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := mountDevImage(); err != nil {
|
||||||
|
return 1, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kill any hanging debug bridges that might take up port 3222.
|
||||||
|
exec.Command("killall", "idevicedebugserverproxy").Run()
|
||||||
|
|
||||||
|
closer, err := startDebugBridge()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "go_darwin_arm_exec: %v\n", err)
|
return 1, err
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
|
defer closer()
|
||||||
|
|
||||||
|
if err := run(appdir, bundleID, os.Args[2:]); err != nil {
|
||||||
|
// If the lldb driver completed with an exit code, use that.
|
||||||
|
if err, ok := err.(*exec.ExitError); ok {
|
||||||
|
if ws, ok := err.Sys().(interface{ ExitStatus() int }); ok {
|
||||||
|
return ws.ExitStatus(), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1, err
|
||||||
|
}
|
||||||
|
return 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getenv(envvar string) string {
|
func getenv(envvar string) string {
|
||||||
|
|
@ -140,9 +167,7 @@ func getenv(envvar string) string {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
func run(bin string, args []string) (err error) {
|
func assembleApp(appdir, bin string) error {
|
||||||
appdir := filepath.Join(tmpdir, "gotest.app")
|
|
||||||
os.RemoveAll(appdir)
|
|
||||||
if err := os.MkdirAll(appdir, 0755); err != nil {
|
if err := os.MkdirAll(appdir, 0755); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -182,285 +207,325 @@ func run(bin string, args []string) (err error) {
|
||||||
if err := cmd.Run(); err != nil {
|
if err := cmd.Run(); err != nil {
|
||||||
return fmt.Errorf("codesign: %v", err)
|
return fmt.Errorf("codesign: %v", err)
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
oldwd, err := os.Getwd()
|
// mountDevImage ensures a developer image is mounted on the device.
|
||||||
|
// The image contains the device lldb server for idevicedebugserverproxy
|
||||||
|
// to connect to.
|
||||||
|
func mountDevImage() error {
|
||||||
|
// Check for existing mount.
|
||||||
|
cmd := idevCmd(exec.Command("ideviceimagemounter", "-l", "-x"))
|
||||||
|
out, err := cmd.CombinedOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
os.Stderr.Write(out)
|
||||||
|
return fmt.Errorf("ideviceimagemounter: %v", err)
|
||||||
}
|
}
|
||||||
if err := os.Chdir(filepath.Join(appdir, "..")); err != nil {
|
var info struct {
|
||||||
return err
|
Dict struct {
|
||||||
|
Data []byte `xml:",innerxml"`
|
||||||
|
} `xml:"dict"`
|
||||||
}
|
}
|
||||||
defer os.Chdir(oldwd)
|
if err := xml.Unmarshal(out, &info); err != nil {
|
||||||
|
return fmt.Errorf("mountDevImage: failed to decode mount information: %v", err)
|
||||||
// Setting up lldb is flaky. The test binary itself runs when
|
}
|
||||||
// started is set to true. Everything before that is considered
|
dict, err := parsePlistDict(info.Dict.Data)
|
||||||
// part of the setup and is retried.
|
|
||||||
started := false
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil {
|
|
||||||
if w, ok := r.(waitPanic); ok {
|
|
||||||
err = w.err
|
|
||||||
if !started {
|
|
||||||
fmt.Printf("lldb setup error: %v\n", err)
|
|
||||||
err = errRetry
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
panic(r)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
defer exec.Command("killall", "ios-deploy").Run() // cleanup
|
|
||||||
exec.Command("killall", "ios-deploy").Run()
|
|
||||||
|
|
||||||
var opts options
|
|
||||||
opts, args = parseArgs(args)
|
|
||||||
|
|
||||||
// ios-deploy invokes lldb to give us a shell session with the app.
|
|
||||||
s, err := newSession(appdir, args, opts)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("mountDevImage: failed to parse mount information: %v", err)
|
||||||
}
|
}
|
||||||
defer func() {
|
if dict["ImagePresent"] == "true" && dict["Status"] == "Complete" {
|
||||||
b := s.out.Bytes()
|
|
||||||
if err == nil && !debug {
|
|
||||||
i := bytes.Index(b, []byte("(lldb) process continue"))
|
|
||||||
if i > 0 {
|
|
||||||
b = b[i:]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
os.Stdout.Write(b)
|
|
||||||
}()
|
|
||||||
|
|
||||||
cond := func(out *buf) bool {
|
|
||||||
i0 := s.out.LastIndex([]byte("(lldb)"))
|
|
||||||
i1 := s.out.LastIndex([]byte("fruitstrap"))
|
|
||||||
i2 := s.out.LastIndex([]byte(" connect"))
|
|
||||||
return i0 > 0 && i1 > 0 && i2 > 0
|
|
||||||
}
|
|
||||||
if err := s.wait("lldb start", cond, 15*time.Second); err != nil {
|
|
||||||
panic(waitPanic{err})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Script LLDB. Oh dear.
|
|
||||||
s.do(`process handle SIGHUP --stop false --pass true --notify false`)
|
|
||||||
s.do(`process handle SIGPIPE --stop false --pass true --notify false`)
|
|
||||||
s.do(`process handle SIGUSR1 --stop false --pass true --notify false`)
|
|
||||||
s.do(`process handle SIGCONT --stop false --pass true --notify false`)
|
|
||||||
s.do(`process handle SIGSEGV --stop false --pass true --notify false`) // does not work
|
|
||||||
s.do(`process handle SIGBUS --stop false --pass true --notify false`) // does not work
|
|
||||||
|
|
||||||
if opts.lldb {
|
|
||||||
_, err := io.Copy(s.in, os.Stdin)
|
|
||||||
if err != io.EOF {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
// Some devices only give us an ImageSignature key.
|
||||||
started = true
|
if _, exists := dict["ImageSignature"]; exists {
|
||||||
|
|
||||||
s.doCmd("run", "stop reason = signal SIGINT", 20*time.Second)
|
|
||||||
|
|
||||||
startTestsLen := s.out.Len()
|
|
||||||
fmt.Fprintln(s.in, `process continue`)
|
|
||||||
|
|
||||||
passed := func(out *buf) bool {
|
|
||||||
// Just to make things fun, lldb sometimes translates \n into \r\n.
|
|
||||||
return s.out.LastIndex([]byte("\nPASS\n")) > startTestsLen ||
|
|
||||||
s.out.LastIndex([]byte("\nPASS\r")) > startTestsLen ||
|
|
||||||
s.out.LastIndex([]byte("\n(lldb) PASS\n")) > startTestsLen ||
|
|
||||||
s.out.LastIndex([]byte("\n(lldb) PASS\r")) > startTestsLen ||
|
|
||||||
s.out.LastIndex([]byte("exited with status = 0 (0x00000000) \n")) > startTestsLen ||
|
|
||||||
s.out.LastIndex([]byte("exited with status = 0 (0x00000000) \r")) > startTestsLen
|
|
||||||
}
|
|
||||||
err = s.wait("test completion", passed, opts.timeout)
|
|
||||||
if passed(s.out) {
|
|
||||||
// The returned lldb error code is usually non-zero.
|
|
||||||
// We check for test success by scanning for the final
|
|
||||||
// PASS returned by the test harness, assuming the worst
|
|
||||||
// in its absence.
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return err
|
// No image is mounted. Find a suitable image.
|
||||||
}
|
imgPath, err := findDevImage()
|
||||||
|
|
||||||
type lldbSession struct {
|
|
||||||
cmd *exec.Cmd
|
|
||||||
in *os.File
|
|
||||||
out *buf
|
|
||||||
timedout chan struct{}
|
|
||||||
exited chan error
|
|
||||||
}
|
|
||||||
|
|
||||||
func newSession(appdir string, args []string, opts options) (*lldbSession, error) {
|
|
||||||
lldbr, in, err := os.Pipe()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
s := &lldbSession{
|
sigPath := imgPath + ".signature"
|
||||||
in: in,
|
cmd = idevCmd(exec.Command("ideviceimagemounter", imgPath, sigPath))
|
||||||
out: new(buf),
|
if out, err := cmd.CombinedOutput(); err != nil {
|
||||||
exited: make(chan error),
|
os.Stderr.Write(out)
|
||||||
|
return fmt.Errorf("ideviceimagemounter: %v", err)
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
iosdPath, err := exec.LookPath("ios-deploy")
|
// findDevImage use the device iOS version and build to locate a suitable
|
||||||
|
// developer image.
|
||||||
|
func findDevImage() (string, error) {
|
||||||
|
cmd := idevCmd(exec.Command("ideviceinfo"))
|
||||||
|
out, err := cmd.Output()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return "", fmt.Errorf("ideviceinfo: %v", err)
|
||||||
}
|
}
|
||||||
cmdArgs := []string{
|
var iosVer, buildVer string
|
||||||
// lldb tries to be clever with terminals.
|
lines := bytes.Split(out, []byte("\n"))
|
||||||
// So we wrap it in script(1) and be clever
|
for _, line := range lines {
|
||||||
// right back at it.
|
spl := bytes.SplitN(line, []byte(": "), 2)
|
||||||
"script",
|
if len(spl) != 2 {
|
||||||
"-q", "-t", "0",
|
|
||||||
"/dev/null",
|
|
||||||
|
|
||||||
iosdPath,
|
|
||||||
"--debug",
|
|
||||||
"-u",
|
|
||||||
"-r",
|
|
||||||
"-n",
|
|
||||||
`--args=` + strings.Join(args, " ") + ``,
|
|
||||||
"--bundle", appdir,
|
|
||||||
}
|
|
||||||
if deviceID != "" {
|
|
||||||
cmdArgs = append(cmdArgs, "--id", deviceID)
|
|
||||||
}
|
|
||||||
s.cmd = exec.Command(cmdArgs[0], cmdArgs[1:]...)
|
|
||||||
if debug {
|
|
||||||
log.Println(strings.Join(s.cmd.Args, " "))
|
|
||||||
}
|
|
||||||
|
|
||||||
var out io.Writer = s.out
|
|
||||||
if opts.lldb {
|
|
||||||
out = io.MultiWriter(out, os.Stderr)
|
|
||||||
}
|
|
||||||
s.cmd.Stdout = out
|
|
||||||
s.cmd.Stderr = out // everything of interest is on stderr
|
|
||||||
s.cmd.Stdin = lldbr
|
|
||||||
|
|
||||||
if err := s.cmd.Start(); err != nil {
|
|
||||||
return nil, fmt.Errorf("ios-deploy failed to start: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Manage the -test.timeout here, outside of the test. There is a lot
|
|
||||||
// of moving parts in an iOS test harness (notably lldb) that can
|
|
||||||
// swallow useful stdio or cause its own ruckus.
|
|
||||||
if opts.timeout > 1*time.Second {
|
|
||||||
s.timedout = make(chan struct{})
|
|
||||||
time.AfterFunc(opts.timeout-1*time.Second, func() {
|
|
||||||
close(s.timedout)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
s.exited <- s.cmd.Wait()
|
|
||||||
}()
|
|
||||||
|
|
||||||
return s, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *lldbSession) do(cmd string) { s.doCmd(cmd, "(lldb)", 0) }
|
|
||||||
|
|
||||||
func (s *lldbSession) doCmd(cmd string, waitFor string, extraTimeout time.Duration) {
|
|
||||||
startLen := s.out.Len()
|
|
||||||
fmt.Fprintln(s.in, cmd)
|
|
||||||
cond := func(out *buf) bool {
|
|
||||||
i := s.out.LastIndex([]byte(waitFor))
|
|
||||||
return i > startLen
|
|
||||||
}
|
|
||||||
if err := s.wait(fmt.Sprintf("running cmd %q", cmd), cond, extraTimeout); err != nil {
|
|
||||||
panic(waitPanic{err})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *lldbSession) wait(reason string, cond func(out *buf) bool, extraTimeout time.Duration) error {
|
|
||||||
doTimeout := 2*time.Second + extraTimeout
|
|
||||||
doTimedout := time.After(doTimeout)
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-s.timedout:
|
|
||||||
if p := s.cmd.Process; p != nil {
|
|
||||||
p.Kill()
|
|
||||||
}
|
|
||||||
return fmt.Errorf("test timeout (%s)", reason)
|
|
||||||
case <-doTimedout:
|
|
||||||
if p := s.cmd.Process; p != nil {
|
|
||||||
p.Kill()
|
|
||||||
}
|
|
||||||
return fmt.Errorf("command timeout (%s for %v)", reason, doTimeout)
|
|
||||||
case err := <-s.exited:
|
|
||||||
return fmt.Errorf("exited (%s: %v)", reason, err)
|
|
||||||
default:
|
|
||||||
if cond(s.out) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
time.Sleep(20 * time.Millisecond)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type buf struct {
|
|
||||||
mu sync.Mutex
|
|
||||||
buf []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *buf) Write(in []byte) (n int, err error) {
|
|
||||||
w.mu.Lock()
|
|
||||||
defer w.mu.Unlock()
|
|
||||||
w.buf = append(w.buf, in...)
|
|
||||||
return len(in), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *buf) LastIndex(sep []byte) int {
|
|
||||||
w.mu.Lock()
|
|
||||||
defer w.mu.Unlock()
|
|
||||||
return bytes.LastIndex(w.buf, sep)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *buf) Bytes() []byte {
|
|
||||||
w.mu.Lock()
|
|
||||||
defer w.mu.Unlock()
|
|
||||||
|
|
||||||
b := make([]byte, len(w.buf))
|
|
||||||
copy(b, w.buf)
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *buf) Len() int {
|
|
||||||
w.mu.Lock()
|
|
||||||
defer w.mu.Unlock()
|
|
||||||
return len(w.buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
type waitPanic struct {
|
|
||||||
err error
|
|
||||||
}
|
|
||||||
|
|
||||||
type options struct {
|
|
||||||
timeout time.Duration
|
|
||||||
lldb bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseArgs(binArgs []string) (opts options, remainingArgs []string) {
|
|
||||||
var flagArgs []string
|
|
||||||
for _, arg := range binArgs {
|
|
||||||
if strings.Contains(arg, "-test.timeout") {
|
|
||||||
flagArgs = append(flagArgs, arg)
|
|
||||||
}
|
|
||||||
if strings.Contains(arg, "-lldb") {
|
|
||||||
flagArgs = append(flagArgs, arg)
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
remainingArgs = append(remainingArgs, arg)
|
key, val := string(spl[0]), string(spl[1])
|
||||||
|
switch key {
|
||||||
|
case "ProductVersion":
|
||||||
|
iosVer = val
|
||||||
|
case "BuildVersion":
|
||||||
|
buildVer = val
|
||||||
|
}
|
||||||
}
|
}
|
||||||
f := flag.NewFlagSet("", flag.ContinueOnError)
|
if iosVer == "" || buildVer == "" {
|
||||||
f.DurationVar(&opts.timeout, "test.timeout", 10*time.Minute, "")
|
return "", errors.New("failed to parse ideviceinfo output")
|
||||||
f.BoolVar(&opts.lldb, "lldb", false, "")
|
}
|
||||||
f.Parse(flagArgs)
|
verSplit := strings.Split(iosVer, ".")
|
||||||
return opts, remainingArgs
|
if len(verSplit) > 2 {
|
||||||
|
// Developer images are specific to major.minor ios version.
|
||||||
|
// Cut off the patch version.
|
||||||
|
iosVer = strings.Join(verSplit[:2], ".")
|
||||||
|
}
|
||||||
|
sdkBase := "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport"
|
||||||
|
patterns := []string{fmt.Sprintf("%s (%s)", iosVer, buildVer), fmt.Sprintf("%s (*)", iosVer), fmt.Sprintf("%s*", iosVer)}
|
||||||
|
for _, pattern := range patterns {
|
||||||
|
matches, err := filepath.Glob(filepath.Join(sdkBase, pattern, "DeveloperDiskImage.dmg"))
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("findDevImage: %v", err)
|
||||||
|
}
|
||||||
|
if len(matches) > 0 {
|
||||||
|
return matches[0], nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "", fmt.Errorf("failed to find matching developer image for iOS version %s build %s", iosVer, buildVer)
|
||||||
|
}
|
||||||
|
|
||||||
|
// startDebugBridge ensures that the idevicedebugserverproxy runs on
|
||||||
|
// port 3222.
|
||||||
|
func startDebugBridge() (func(), error) {
|
||||||
|
errChan := make(chan error, 1)
|
||||||
|
cmd := idevCmd(exec.Command("idevicedebugserverproxy", "3222"))
|
||||||
|
var stderr bytes.Buffer
|
||||||
|
cmd.Stderr = &stderr
|
||||||
|
if err := cmd.Start(); err != nil {
|
||||||
|
return nil, fmt.Errorf("idevicedebugserverproxy: %v", err)
|
||||||
|
}
|
||||||
|
go func() {
|
||||||
|
if err := cmd.Wait(); err != nil {
|
||||||
|
if _, ok := err.(*exec.ExitError); ok {
|
||||||
|
errChan <- fmt.Errorf("idevicedebugserverproxy: %s", stderr.Bytes())
|
||||||
|
} else {
|
||||||
|
errChan <- fmt.Errorf("idevicedebugserverproxy: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
errChan <- nil
|
||||||
|
}()
|
||||||
|
closer := func() {
|
||||||
|
cmd.Process.Kill()
|
||||||
|
<-errChan
|
||||||
|
}
|
||||||
|
// Dial localhost:3222 to ensure the proxy is ready.
|
||||||
|
delay := time.Second / 4
|
||||||
|
for attempt := 0; attempt < 5; attempt++ {
|
||||||
|
conn, err := net.DialTimeout("tcp", "localhost:3222", 5*time.Second)
|
||||||
|
if err == nil {
|
||||||
|
conn.Close()
|
||||||
|
return closer, nil
|
||||||
|
}
|
||||||
|
select {
|
||||||
|
case <-time.After(delay):
|
||||||
|
delay *= 2
|
||||||
|
case err := <-errChan:
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closer()
|
||||||
|
return nil, errors.New("failed to set up idevicedebugserverproxy")
|
||||||
|
}
|
||||||
|
|
||||||
|
// findDeviceAppPath returns the device path to the app with the
|
||||||
|
// given bundle ID. It parses the output of ideviceinstaller -l -o xml,
|
||||||
|
// looking for the bundle ID and the corresponding Path value.
|
||||||
|
func findDeviceAppPath(bundleID string) (string, error) {
|
||||||
|
cmd := idevCmd(exec.Command("ideviceinstaller", "-l", "-o", "xml"))
|
||||||
|
out, err := cmd.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
os.Stderr.Write(out)
|
||||||
|
return "", fmt.Errorf("ideviceinstaller: -l -o xml %v", err)
|
||||||
|
}
|
||||||
|
var list struct {
|
||||||
|
Apps []struct {
|
||||||
|
Data []byte `xml:",innerxml"`
|
||||||
|
} `xml:"array>dict"`
|
||||||
|
}
|
||||||
|
if err := xml.Unmarshal(out, &list); err != nil {
|
||||||
|
return "", fmt.Errorf("failed to parse ideviceinstaller output: %v", err)
|
||||||
|
}
|
||||||
|
for _, app := range list.Apps {
|
||||||
|
values, err := parsePlistDict(app.Data)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("findDeviceAppPath: failed to parse app dict: %v", err)
|
||||||
|
}
|
||||||
|
if values["CFBundleIdentifier"] == bundleID {
|
||||||
|
if path, ok := values["Path"]; ok {
|
||||||
|
return path, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "", fmt.Errorf("failed to find device path for bundle: %s", bundleID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse an xml encoded plist. Plist values are mapped to string.
|
||||||
|
func parsePlistDict(dict []byte) (map[string]string, error) {
|
||||||
|
d := xml.NewDecoder(bytes.NewReader(dict))
|
||||||
|
values := make(map[string]string)
|
||||||
|
var key string
|
||||||
|
var hasKey bool
|
||||||
|
for {
|
||||||
|
tok, err := d.Token()
|
||||||
|
if err == io.EOF {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if tok, ok := tok.(xml.StartElement); ok {
|
||||||
|
if tok.Name.Local == "key" {
|
||||||
|
if err := d.DecodeElement(&key, &tok); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
hasKey = true
|
||||||
|
} else if hasKey {
|
||||||
|
var val string
|
||||||
|
var err error
|
||||||
|
switch n := tok.Name.Local; n {
|
||||||
|
case "true", "false":
|
||||||
|
// Bools are represented as <true/> and <false/>.
|
||||||
|
val = n
|
||||||
|
err = d.Skip()
|
||||||
|
default:
|
||||||
|
err = d.DecodeElement(&val, &tok)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
values[key] = val
|
||||||
|
hasKey = false
|
||||||
|
} else {
|
||||||
|
if err := d.Skip(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return values, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func uninstall(bundleID string) error {
|
||||||
|
cmd := idevCmd(exec.Command(
|
||||||
|
"ideviceinstaller",
|
||||||
|
"-U", bundleID,
|
||||||
|
))
|
||||||
|
if out, err := cmd.CombinedOutput(); err != nil {
|
||||||
|
os.Stderr.Write(out)
|
||||||
|
return fmt.Errorf("ideviceinstaller -U %q: %s", bundleID, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func install(appdir string) error {
|
||||||
|
attempt := 0
|
||||||
|
for {
|
||||||
|
cmd := idevCmd(exec.Command(
|
||||||
|
"ideviceinstaller",
|
||||||
|
"-i", appdir,
|
||||||
|
))
|
||||||
|
if out, err := cmd.CombinedOutput(); err != nil {
|
||||||
|
// Sometimes, installing the app fails for some reason.
|
||||||
|
// Give the device a few seconds and try again.
|
||||||
|
if attempt < 5 {
|
||||||
|
time.Sleep(5 * time.Second)
|
||||||
|
attempt++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
os.Stderr.Write(out)
|
||||||
|
return fmt.Errorf("ideviceinstaller -i %q: %v (%d attempts)", appdir, err, attempt)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func idevCmd(cmd *exec.Cmd) *exec.Cmd {
|
||||||
|
if deviceID != "" {
|
||||||
|
// Inject -u device_id after the executable, but before the arguments.
|
||||||
|
args := []string{cmd.Args[0], "-u", deviceID}
|
||||||
|
cmd.Args = append(args, cmd.Args[1:]...)
|
||||||
|
}
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func run(appdir, bundleID string, args []string) error {
|
||||||
|
var env []string
|
||||||
|
for _, e := range os.Environ() {
|
||||||
|
// Don't override TMPDIR on the device.
|
||||||
|
if strings.HasPrefix(e, "TMPDIR=") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
env = append(env, e)
|
||||||
|
}
|
||||||
|
attempt := 0
|
||||||
|
for {
|
||||||
|
// The device app path reported by the device might be stale, so retry
|
||||||
|
// the lookup of the device path along with the lldb launching below.
|
||||||
|
deviceapp, err := findDeviceAppPath(bundleID)
|
||||||
|
if err != nil {
|
||||||
|
// The device app path might not yet exist for a newly installed app.
|
||||||
|
if attempt == 5 {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
attempt++
|
||||||
|
time.Sleep(5 * time.Second)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
lldb := exec.Command(
|
||||||
|
"python",
|
||||||
|
"-", // Read script from stdin.
|
||||||
|
appdir,
|
||||||
|
deviceapp,
|
||||||
|
)
|
||||||
|
lldb.Args = append(lldb.Args, args...)
|
||||||
|
lldb.Env = env
|
||||||
|
lldb.Stdin = strings.NewReader(lldbDriver)
|
||||||
|
lldb.Stdout = os.Stdout
|
||||||
|
var out bytes.Buffer
|
||||||
|
lldb.Stderr = io.MultiWriter(&out, os.Stderr)
|
||||||
|
err = lldb.Start()
|
||||||
|
if err == nil {
|
||||||
|
// Forward SIGQUIT to the lldb driver which in turn will forward
|
||||||
|
// to the running program.
|
||||||
|
sigs := make(chan os.Signal, 1)
|
||||||
|
signal.Notify(sigs, syscall.SIGQUIT)
|
||||||
|
proc := lldb.Process
|
||||||
|
go func() {
|
||||||
|
for sig := range sigs {
|
||||||
|
proc.Signal(sig)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
err = lldb.Wait()
|
||||||
|
signal.Stop(sigs)
|
||||||
|
close(sigs)
|
||||||
|
}
|
||||||
|
// If the program was not started it can be retried without papering over
|
||||||
|
// real test failures.
|
||||||
|
started := bytes.HasPrefix(out.Bytes(), []byte("lldb: running program"))
|
||||||
|
if started || err == nil || attempt == 5 {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Sometimes, the app was not yet ready to launch or the device path was
|
||||||
|
// stale. Retry.
|
||||||
|
attempt++
|
||||||
|
time.Sleep(5 * time.Second)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func copyLocalDir(dst, src string) error {
|
func copyLocalDir(dst, src string) error {
|
||||||
|
|
@ -656,3 +721,91 @@ const resourceRules = `<?xml version="1.0" encoding="UTF-8"?>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
`
|
`
|
||||||
|
|
||||||
|
const lldbDriver = `
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import signal
|
||||||
|
|
||||||
|
exe, device_exe, args = sys.argv[1], sys.argv[2], sys.argv[3:]
|
||||||
|
|
||||||
|
env = []
|
||||||
|
for k, v in os.environ.items():
|
||||||
|
env.append(k + "=" + v)
|
||||||
|
|
||||||
|
sys.path.append('/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Resources/Python')
|
||||||
|
|
||||||
|
import lldb
|
||||||
|
|
||||||
|
debugger = lldb.SBDebugger.Create()
|
||||||
|
debugger.SetAsync(True)
|
||||||
|
debugger.SkipLLDBInitFiles(True)
|
||||||
|
|
||||||
|
err = lldb.SBError()
|
||||||
|
target = debugger.CreateTarget(exe, None, 'remote-ios', True, err)
|
||||||
|
if not target.IsValid() or not err.Success():
|
||||||
|
sys.stderr.write("lldb: failed to setup up target: %s\n" % (err))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
target.modules[0].SetPlatformFileSpec(lldb.SBFileSpec(device_exe))
|
||||||
|
|
||||||
|
listener = debugger.GetListener()
|
||||||
|
process = target.ConnectRemote(listener, 'connect://localhost:3222', None, err)
|
||||||
|
if not err.Success():
|
||||||
|
sys.stderr.write("lldb: failed to connect to remote target: %s\n" % (err))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# Don't stop on signals.
|
||||||
|
sigs = process.GetUnixSignals()
|
||||||
|
for i in range(0, sigs.GetNumSignals()):
|
||||||
|
sig = sigs.GetSignalAtIndex(i)
|
||||||
|
sigs.SetShouldStop(sig, False)
|
||||||
|
sigs.SetShouldNotify(sig, False)
|
||||||
|
|
||||||
|
event = lldb.SBEvent()
|
||||||
|
running = False
|
||||||
|
prev_handler = None
|
||||||
|
while True:
|
||||||
|
if not listener.WaitForEvent(1, event):
|
||||||
|
continue
|
||||||
|
if not lldb.SBProcess.EventIsProcessEvent(event):
|
||||||
|
continue
|
||||||
|
if running:
|
||||||
|
# Pass through stdout and stderr.
|
||||||
|
while True:
|
||||||
|
out = process.GetSTDOUT(8192)
|
||||||
|
if not out:
|
||||||
|
break
|
||||||
|
sys.stdout.write(out)
|
||||||
|
while True:
|
||||||
|
out = process.GetSTDERR(8192)
|
||||||
|
if not out:
|
||||||
|
break
|
||||||
|
sys.stderr.write(out)
|
||||||
|
state = process.GetStateFromEvent(event)
|
||||||
|
if state in [lldb.eStateCrashed, lldb.eStateDetached, lldb.eStateUnloaded, lldb.eStateExited]:
|
||||||
|
if running:
|
||||||
|
signal.signal(signal.SIGQUIT, prev_handler)
|
||||||
|
break
|
||||||
|
elif state == lldb.eStateConnected:
|
||||||
|
process.RemoteLaunch(args, env, None, None, None, None, 0, False, err)
|
||||||
|
if not err.Success():
|
||||||
|
sys.stderr.write("lldb: failed to launch remote process: %s\n" % (err))
|
||||||
|
process.Kill()
|
||||||
|
debugger.Terminate()
|
||||||
|
sys.exit(1)
|
||||||
|
# Forward SIGQUIT to the program.
|
||||||
|
def signal_handler(signal, frame):
|
||||||
|
process.Signal(signal)
|
||||||
|
prev_handler = signal.signal(signal.SIGQUIT, signal_handler)
|
||||||
|
# Tell the Go driver that the program is running and should not be retried.
|
||||||
|
sys.stderr.write("lldb: running program\n")
|
||||||
|
running = True
|
||||||
|
# Process stops once at the beginning. Continue.
|
||||||
|
process.Continue()
|
||||||
|
|
||||||
|
exitStatus = process.GetExitStatus()
|
||||||
|
process.Kill()
|
||||||
|
debugger.Terminate()
|
||||||
|
sys.exit(exitStatus)
|
||||||
|
`
|
||||||
|
|
|
||||||
2
misc/nacl/testdata/mime.types
vendored
2
misc/nacl/testdata/mime.types
vendored
|
|
@ -9,7 +9,7 @@
|
||||||
# content languages and encodings, so choose them carefully.
|
# content languages and encodings, so choose them carefully.
|
||||||
#
|
#
|
||||||
# Internet media types should be registered as described in RFC 4288.
|
# Internet media types should be registered as described in RFC 4288.
|
||||||
# The registry is at <http://www.iana.org/assignments/media-types/>.
|
# The registry is at <https://www.iana.org/assignments/media-types/>.
|
||||||
#
|
#
|
||||||
# MIME type (lowercased) Extensions
|
# MIME type (lowercased) Extensions
|
||||||
# ============================================ ==========
|
# ============================================ ==========
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
This directory contains helper file for trace viewer (`go tool trace`).
|
This directory contains helper file for trace viewer (`go tool trace`).
|
||||||
|
|
||||||
`trace_viewer_lean.html` was generated by following
|
`trace_viewer_full.html` was generated by following
|
||||||
[instructions](https://github.com/catapult-project/catapult/blob/master/tracing/docs/embedding-trace-viewer.md)
|
[instructions](https://github.com/catapult-project/catapult/blob/master/tracing/docs/embedding-trace-viewer.md)
|
||||||
on revision `623a005a3ffa9de13c4b92bc72290e7bcd1ca591`
|
on revision `dc970d3e1f7b3da5a2849de70ff253acdb70148f`
|
||||||
of [catapult](https://github.com/catapult-project/catapult) using:
|
of [catapult](https://github.com/catapult-project/catapult) using:
|
||||||
```
|
```
|
||||||
catapult$ ./tracing/bin/vulcanize_trace_viewer --config=full
|
catapult$ ./tracing/bin/vulcanize_trace_viewer --config=full
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
14
misc/wasm/go_js_wasm_exec
Executable file
14
misc/wasm/go_js_wasm_exec
Executable file
|
|
@ -0,0 +1,14 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Copyright 2018 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.
|
||||||
|
|
||||||
|
SOURCE="${BASH_SOURCE[0]}"
|
||||||
|
while [ -h "$SOURCE" ]; do
|
||||||
|
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
||||||
|
SOURCE="$(readlink "$SOURCE")"
|
||||||
|
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"
|
||||||
|
done
|
||||||
|
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
||||||
|
|
||||||
|
exec node "$DIR/wasm_exec.js" "$@"
|
||||||
30
misc/wasm/wasm_exec.html
Normal file
30
misc/wasm/wasm_exec.html
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
<!doctype html>
|
||||||
|
<!--
|
||||||
|
Copyright 2018 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.
|
||||||
|
-->
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Go wasm</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<script src="wasm_exec.js"></script>
|
||||||
|
<script>
|
||||||
|
async function loadAndCompile() {
|
||||||
|
let resp = await fetch("test.wasm");
|
||||||
|
let bytes = await resp.arrayBuffer();
|
||||||
|
await go.compile(bytes);
|
||||||
|
document.getElementById("runButton").disabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
loadAndCompile();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button onClick="console.clear(); go.run();" id="runButton" disabled>Run</button>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
335
misc/wasm/wasm_exec.js
Executable file
335
misc/wasm/wasm_exec.js
Executable file
|
|
@ -0,0 +1,335 @@
|
||||||
|
// Copyright 2018 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.
|
||||||
|
|
||||||
|
(() => {
|
||||||
|
let args = ["js"];
|
||||||
|
|
||||||
|
// Map web browser API and Node.js API to a single common API (preferring web standards over Node.js API).
|
||||||
|
const isNodeJS = typeof process !== "undefined";
|
||||||
|
if (isNodeJS) {
|
||||||
|
if (process.argv.length < 3) {
|
||||||
|
process.stderr.write("usage: go_js_wasm_exec [wasm binary]\n");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
args = args.concat(process.argv.slice(3));
|
||||||
|
global.require = require;
|
||||||
|
|
||||||
|
global.fs = require("fs");
|
||||||
|
|
||||||
|
const nodeCrypto = require("crypto");
|
||||||
|
global.crypto = {
|
||||||
|
getRandomValues(b) {
|
||||||
|
nodeCrypto.randomFillSync(b);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const now = () => {
|
||||||
|
const [sec, nsec] = process.hrtime();
|
||||||
|
return sec * 1000 + nsec / 1000000;
|
||||||
|
};
|
||||||
|
global.performance = {
|
||||||
|
timeOrigin: Date.now() - now(),
|
||||||
|
now: now,
|
||||||
|
};
|
||||||
|
|
||||||
|
const util = require("util");
|
||||||
|
global.TextEncoder = util.TextEncoder;
|
||||||
|
global.TextDecoder = util.TextDecoder;
|
||||||
|
} else {
|
||||||
|
window.global = window;
|
||||||
|
|
||||||
|
global.process = {
|
||||||
|
env: {},
|
||||||
|
exit(code) {
|
||||||
|
if (code !== 0) {
|
||||||
|
console.warn("exit code:", code);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let outputBuf = "";
|
||||||
|
global.fs = {
|
||||||
|
constants: {},
|
||||||
|
writeSync(fd, buf) {
|
||||||
|
outputBuf += decoder.decode(buf);
|
||||||
|
const nl = outputBuf.lastIndexOf("\n");
|
||||||
|
if (nl != -1) {
|
||||||
|
console.log(outputBuf.substr(0, nl));
|
||||||
|
outputBuf = outputBuf.substr(nl + 1);
|
||||||
|
}
|
||||||
|
return buf.length;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const encoder = new TextEncoder("utf-8");
|
||||||
|
const decoder = new TextDecoder("utf-8");
|
||||||
|
|
||||||
|
let mod, inst;
|
||||||
|
let values = []; // TODO: garbage collection
|
||||||
|
|
||||||
|
const mem = () => {
|
||||||
|
// The buffer may change when requesting more memory.
|
||||||
|
return new DataView(inst.exports.mem.buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
const setInt64 = (addr, v) => {
|
||||||
|
mem().setUint32(addr + 0, v, true);
|
||||||
|
mem().setUint32(addr + 4, Math.floor(v / 4294967296), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
const getInt64 = (addr) => {
|
||||||
|
const low = mem().getUint32(addr + 0, true);
|
||||||
|
const high = mem().getInt32(addr + 4, true);
|
||||||
|
return low + high * 4294967296;
|
||||||
|
}
|
||||||
|
|
||||||
|
const loadValue = (addr) => {
|
||||||
|
const id = mem().getUint32(addr, true);
|
||||||
|
return values[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
const storeValue = (addr, v) => {
|
||||||
|
if (v === undefined) {
|
||||||
|
mem().setUint32(addr, 0, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (v === null) {
|
||||||
|
mem().setUint32(addr, 1, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
values.push(v);
|
||||||
|
mem().setUint32(addr, values.length - 1, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
const loadSlice = (addr) => {
|
||||||
|
const array = getInt64(addr + 0);
|
||||||
|
const len = getInt64(addr + 8);
|
||||||
|
return new Uint8Array(inst.exports.mem.buffer, array, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
const loadSliceOfValues = (addr) => {
|
||||||
|
const array = getInt64(addr + 0);
|
||||||
|
const len = getInt64(addr + 8);
|
||||||
|
const a = new Array(len);
|
||||||
|
for (let i = 0; i < len; i++) {
|
||||||
|
const id = mem().getUint32(array + i * 4, true);
|
||||||
|
a[i] = values[id];
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
const loadString = (addr) => {
|
||||||
|
const saddr = getInt64(addr + 0);
|
||||||
|
const len = getInt64(addr + 8);
|
||||||
|
return decoder.decode(new DataView(inst.exports.mem.buffer, saddr, len));
|
||||||
|
}
|
||||||
|
|
||||||
|
global.go = {
|
||||||
|
async compileAndRun(source) {
|
||||||
|
await go.compile(source);
|
||||||
|
await go.run();
|
||||||
|
},
|
||||||
|
|
||||||
|
async compile(source) {
|
||||||
|
mod = await WebAssembly.compile(source);
|
||||||
|
},
|
||||||
|
|
||||||
|
async run() {
|
||||||
|
let importObject = {
|
||||||
|
go: {
|
||||||
|
// func wasmExit(code int32)
|
||||||
|
"runtime.wasmExit": (sp) => {
|
||||||
|
process.exit(mem().getInt32(sp + 8, true));
|
||||||
|
},
|
||||||
|
|
||||||
|
// func wasmWrite(fd uintptr, p unsafe.Pointer, n int32)
|
||||||
|
"runtime.wasmWrite": (sp) => {
|
||||||
|
const fd = getInt64(sp + 8);
|
||||||
|
const p = getInt64(sp + 16);
|
||||||
|
const n = mem().getInt32(sp + 24, true);
|
||||||
|
fs.writeSync(fd, new Uint8Array(inst.exports.mem.buffer, p, n));
|
||||||
|
},
|
||||||
|
|
||||||
|
// func nanotime() int64
|
||||||
|
"runtime.nanotime": (sp) => {
|
||||||
|
setInt64(sp + 8, (performance.timeOrigin + performance.now()) * 1000000);
|
||||||
|
},
|
||||||
|
|
||||||
|
// func walltime() (sec int64, nsec int32)
|
||||||
|
"runtime.walltime": (sp) => {
|
||||||
|
const msec = (new Date).getTime();
|
||||||
|
setInt64(sp + 8, msec / 1000);
|
||||||
|
mem().setInt32(sp + 16, (msec % 1000) * 1000000, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
// func boolVal(value bool) Value
|
||||||
|
"syscall/js.boolVal": (sp) => {
|
||||||
|
storeValue(sp + 16, mem().getUint8(sp + 8) !== 0);
|
||||||
|
},
|
||||||
|
|
||||||
|
// func intVal(value int) Value
|
||||||
|
"syscall/js.intVal": (sp) => {
|
||||||
|
storeValue(sp + 16, getInt64(sp + 8));
|
||||||
|
},
|
||||||
|
|
||||||
|
// func floatVal(value float64) Value
|
||||||
|
"syscall/js.floatVal": (sp) => {
|
||||||
|
storeValue(sp + 16, mem().getFloat64(sp + 8, true));
|
||||||
|
},
|
||||||
|
|
||||||
|
// func stringVal(value string) Value
|
||||||
|
"syscall/js.stringVal": (sp) => {
|
||||||
|
storeValue(sp + 24, loadString(sp + 8));
|
||||||
|
},
|
||||||
|
|
||||||
|
// func (v Value) Get(key string) Value
|
||||||
|
"syscall/js.Value.Get": (sp) => {
|
||||||
|
storeValue(sp + 32, Reflect.get(loadValue(sp + 8), loadString(sp + 16)));
|
||||||
|
},
|
||||||
|
|
||||||
|
// func (v Value) set(key string, value Value)
|
||||||
|
"syscall/js.Value.set": (sp) => {
|
||||||
|
Reflect.set(loadValue(sp + 8), loadString(sp + 16), loadValue(sp + 32));
|
||||||
|
},
|
||||||
|
|
||||||
|
// func (v Value) Index(i int) Value
|
||||||
|
"syscall/js.Value.Index": (sp) => {
|
||||||
|
storeValue(sp + 24, Reflect.get(loadValue(sp + 8), getInt64(sp + 16)));
|
||||||
|
},
|
||||||
|
|
||||||
|
// func (v Value) setIndex(i int, value Value)
|
||||||
|
"syscall/js.Value.setIndex": (sp) => {
|
||||||
|
Reflect.set(loadValue(sp + 8), getInt64(sp + 16), loadValue(sp + 24));
|
||||||
|
},
|
||||||
|
|
||||||
|
// func (v Value) call(name string, args []Value) (Value, bool)
|
||||||
|
"syscall/js.Value.call": (sp) => {
|
||||||
|
try {
|
||||||
|
const v = loadValue(sp + 8);
|
||||||
|
const m = Reflect.get(v, loadString(sp + 16));
|
||||||
|
const args = loadSliceOfValues(sp + 32);
|
||||||
|
storeValue(sp + 56, Reflect.apply(m, v, args));
|
||||||
|
mem().setUint8(sp + 60, 1);
|
||||||
|
} catch (err) {
|
||||||
|
storeValue(sp + 56, err);
|
||||||
|
mem().setUint8(sp + 60, 0);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// func (v Value) invoke(args []Value) (Value, bool)
|
||||||
|
"syscall/js.Value.invoke": (sp) => {
|
||||||
|
try {
|
||||||
|
const v = loadValue(sp + 8);
|
||||||
|
const args = loadSliceOfValues(sp + 16);
|
||||||
|
storeValue(sp + 40, Reflect.apply(v, undefined, args));
|
||||||
|
mem().setUint8(sp + 44, 1);
|
||||||
|
} catch (err) {
|
||||||
|
storeValue(sp + 40, err);
|
||||||
|
mem().setUint8(sp + 44, 0);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// func (v Value) new(args []Value) (Value, bool)
|
||||||
|
"syscall/js.Value.new": (sp) => {
|
||||||
|
try {
|
||||||
|
const v = loadValue(sp + 8);
|
||||||
|
const args = loadSliceOfValues(sp + 16);
|
||||||
|
storeValue(sp + 40, Reflect.construct(v, args));
|
||||||
|
mem().setUint8(sp + 44, 1);
|
||||||
|
} catch (err) {
|
||||||
|
storeValue(sp + 40, err);
|
||||||
|
mem().setUint8(sp + 44, 0);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// func (v Value) Float() float64
|
||||||
|
"syscall/js.Value.Float": (sp) => {
|
||||||
|
mem().setFloat64(sp + 16, parseFloat(loadValue(sp + 8)), true);
|
||||||
|
},
|
||||||
|
|
||||||
|
// func (v Value) Int() int
|
||||||
|
"syscall/js.Value.Int": (sp) => {
|
||||||
|
setInt64(sp + 16, parseInt(loadValue(sp + 8)));
|
||||||
|
},
|
||||||
|
|
||||||
|
// func (v Value) Bool() bool
|
||||||
|
"syscall/js.Value.Bool": (sp) => {
|
||||||
|
mem().setUint8(sp + 16, !!loadValue(sp + 8));
|
||||||
|
},
|
||||||
|
|
||||||
|
// func (v Value) Length() int
|
||||||
|
"syscall/js.Value.Length": (sp) => {
|
||||||
|
setInt64(sp + 16, parseInt(loadValue(sp + 8).length));
|
||||||
|
},
|
||||||
|
|
||||||
|
// func (v Value) prepareString() (Value, int)
|
||||||
|
"syscall/js.Value.prepareString": (sp) => {
|
||||||
|
const str = encoder.encode(String(loadValue(sp + 8)));
|
||||||
|
storeValue(sp + 16, str);
|
||||||
|
setInt64(sp + 24, str.length);
|
||||||
|
},
|
||||||
|
|
||||||
|
// func (v Value) loadString(b []byte)
|
||||||
|
"syscall/js.Value.loadString": (sp) => {
|
||||||
|
const str = loadValue(sp + 8);
|
||||||
|
loadSlice(sp + 16).set(str);
|
||||||
|
},
|
||||||
|
|
||||||
|
"debug": (value) => {
|
||||||
|
console.log(value);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
inst = await WebAssembly.instantiate(mod, importObject);
|
||||||
|
values = [undefined, null, global, inst.exports.mem];
|
||||||
|
|
||||||
|
// Pass command line arguments and environment variables to WebAssembly by writing them to the linear memory.
|
||||||
|
let offset = 4096;
|
||||||
|
|
||||||
|
const strPtr = (str) => {
|
||||||
|
let ptr = offset;
|
||||||
|
new Uint8Array(inst.exports.mem.buffer, offset, str.length + 1).set(encoder.encode(str + "\0"));
|
||||||
|
offset += str.length + (8 - (str.length % 8));
|
||||||
|
return ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
const argc = args.length;
|
||||||
|
|
||||||
|
const argvPtrs = [];
|
||||||
|
args.forEach((arg) => {
|
||||||
|
argvPtrs.push(strPtr(arg));
|
||||||
|
});
|
||||||
|
|
||||||
|
const keys = Object.keys(process.env).sort();
|
||||||
|
argvPtrs.push(keys.length);
|
||||||
|
keys.forEach((key) => {
|
||||||
|
argvPtrs.push(strPtr(`${key}=${process.env[key]}`));
|
||||||
|
});
|
||||||
|
|
||||||
|
const argv = offset;
|
||||||
|
argvPtrs.forEach((ptr) => {
|
||||||
|
mem().setUint32(offset, ptr, true);
|
||||||
|
mem().setUint32(offset + 4, 0, true);
|
||||||
|
offset += 8;
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
inst.exports.run(argc, argv);
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isNodeJS) {
|
||||||
|
go.compileAndRun(fs.readFileSync(process.argv[2])).catch((err) => {
|
||||||
|
console.error(err);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
@ -23,17 +23,10 @@ if [ "$GOOS" != "android" ]; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z $GOARM ]; then
|
if [ -n "$GOARM" ] && [ "$GOARM" != "7" ]; then
|
||||||
export GOARM=7
|
|
||||||
fi
|
|
||||||
if [ "$GOARM" != "7" ]; then
|
|
||||||
echo "android only supports GOARM=7, got GOARM=$GOARM" 1>&2
|
echo "android only supports GOARM=7, got GOARM=$GOARM" 1>&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
if [ "$GOARCH" = "" ]; then
|
|
||||||
echo "GOARCH must be set" 1>&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
export CGO_ENABLED=1
|
export CGO_ENABLED=1
|
||||||
unset GOBIN
|
unset GOBIN
|
||||||
|
|
@ -77,8 +70,8 @@ cp -a "${GOROOT}/lib" "${FAKE_GOROOT}/"
|
||||||
cp -a "${pkgdir}" "${FAKE_GOROOT}/pkg/"
|
cp -a "${pkgdir}" "${FAKE_GOROOT}/pkg/"
|
||||||
|
|
||||||
echo '# Syncing test files to android device'
|
echo '# Syncing test files to android device'
|
||||||
adb shell mkdir -p /data/local/tmp/goroot
|
adb $GOANDROID_ADB_FLAGS shell mkdir -p /data/local/tmp/goroot
|
||||||
time adb sync data &> /dev/null
|
time adb $GOANDROID_ADB_FLAGS sync data &> /dev/null
|
||||||
|
|
||||||
export CLEANER=${ANDROID_TEST_DIR}/androidcleaner-$$
|
export CLEANER=${ANDROID_TEST_DIR}/androidcleaner-$$
|
||||||
cp ../misc/android/cleaner.go $CLEANER.go
|
cp ../misc/android/cleaner.go $CLEANER.go
|
||||||
|
|
@ -86,8 +79,8 @@ echo 'var files = `' >> $CLEANER.go
|
||||||
(cd $ANDROID_PRODUCT_OUT/data/local/tmp/goroot; find . >> $CLEANER.go)
|
(cd $ANDROID_PRODUCT_OUT/data/local/tmp/goroot; find . >> $CLEANER.go)
|
||||||
echo '`' >> $CLEANER.go
|
echo '`' >> $CLEANER.go
|
||||||
go build -o $CLEANER $CLEANER.go
|
go build -o $CLEANER $CLEANER.go
|
||||||
adb push $CLEANER /data/local/tmp/cleaner
|
adb $GOANDROID_ADB_FLAGS push $CLEANER /data/local/tmp/cleaner
|
||||||
adb shell /data/local/tmp/cleaner
|
adb $GOANDROID_ADB_FLAGS shell /data/local/tmp/cleaner
|
||||||
|
|
||||||
echo ''
|
echo ''
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ func (he headerError) Error() string {
|
||||||
const (
|
const (
|
||||||
// Type '0' indicates a regular file.
|
// Type '0' indicates a regular file.
|
||||||
TypeReg = '0'
|
TypeReg = '0'
|
||||||
TypeRegA = '\x00' // For legacy support; use TypeReg instead
|
TypeRegA = '\x00' // Deprecated: Use TypeReg instead.
|
||||||
|
|
||||||
// Type '1' to '6' are header-only flags and may not have a data body.
|
// Type '1' to '6' are header-only flags and may not have a data body.
|
||||||
TypeLink = '1' // Hard link
|
TypeLink = '1' // Hard link
|
||||||
|
|
@ -138,7 +138,10 @@ var basicKeys = map[string]bool{
|
||||||
// should do so by creating a new Header and copying the fields
|
// should do so by creating a new Header and copying the fields
|
||||||
// that they are interested in preserving.
|
// that they are interested in preserving.
|
||||||
type Header struct {
|
type Header struct {
|
||||||
Typeflag byte // Type of header entry (should be TypeReg for most files)
|
// Typeflag is the type of header entry.
|
||||||
|
// The zero value is automatically promoted to either TypeReg or TypeDir
|
||||||
|
// depending on the presence of a trailing slash in Name.
|
||||||
|
Typeflag byte
|
||||||
|
|
||||||
Name string // Name of file entry
|
Name string // Name of file entry
|
||||||
Linkname string // Target name of link (valid for TypeLink or TypeSymlink)
|
Linkname string // Target name of link (valid for TypeLink or TypeSymlink)
|
||||||
|
|
@ -184,7 +187,7 @@ type Header struct {
|
||||||
// The key and value should be non-empty UTF-8 strings.
|
// The key and value should be non-empty UTF-8 strings.
|
||||||
//
|
//
|
||||||
// When Writer.WriteHeader is called, PAX records derived from the
|
// When Writer.WriteHeader is called, PAX records derived from the
|
||||||
// the other fields in Header take precedence over PAXRecords.
|
// other fields in Header take precedence over PAXRecords.
|
||||||
PAXRecords map[string]string
|
PAXRecords map[string]string
|
||||||
|
|
||||||
// Format specifies the format of the tar header.
|
// Format specifies the format of the tar header.
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,6 @@ func (tr *Reader) next() (*Header, error) {
|
||||||
// normally be visible to the outside. As such, this loop iterates through
|
// normally be visible to the outside. As such, this loop iterates through
|
||||||
// one or more "header files" until it finds a "normal file".
|
// one or more "header files" until it finds a "normal file".
|
||||||
format := FormatUSTAR | FormatPAX | FormatGNU
|
format := FormatUSTAR | FormatPAX | FormatGNU
|
||||||
loop:
|
|
||||||
for {
|
for {
|
||||||
// Discard the remainder of the file and any padding.
|
// Discard the remainder of the file and any padding.
|
||||||
if err := discard(tr.r, tr.curr.PhysicalRemaining()); err != nil {
|
if err := discard(tr.r, tr.curr.PhysicalRemaining()); err != nil {
|
||||||
|
|
@ -102,7 +101,7 @@ loop:
|
||||||
Format: format,
|
Format: format,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
continue loop // This is a meta header affecting the next header
|
continue // This is a meta header affecting the next header
|
||||||
case TypeGNULongName, TypeGNULongLink:
|
case TypeGNULongName, TypeGNULongLink:
|
||||||
format.mayOnlyBe(FormatGNU)
|
format.mayOnlyBe(FormatGNU)
|
||||||
realname, err := ioutil.ReadAll(tr)
|
realname, err := ioutil.ReadAll(tr)
|
||||||
|
|
@ -117,7 +116,7 @@ loop:
|
||||||
case TypeGNULongLink:
|
case TypeGNULongLink:
|
||||||
gnuLongLink = p.parseString(realname)
|
gnuLongLink = p.parseString(realname)
|
||||||
}
|
}
|
||||||
continue loop // This is a meta header affecting the next header
|
continue // This is a meta header affecting the next header
|
||||||
default:
|
default:
|
||||||
// The old GNU sparse format is handled here since it is technically
|
// The old GNU sparse format is handled here since it is technically
|
||||||
// just a regular file with additional attributes.
|
// just a regular file with additional attributes.
|
||||||
|
|
@ -131,8 +130,12 @@ loop:
|
||||||
if gnuLongLink != "" {
|
if gnuLongLink != "" {
|
||||||
hdr.Linkname = gnuLongLink
|
hdr.Linkname = gnuLongLink
|
||||||
}
|
}
|
||||||
if hdr.Typeflag == TypeRegA && strings.HasSuffix(hdr.Name, "/") {
|
if hdr.Typeflag == TypeRegA {
|
||||||
hdr.Typeflag = TypeDir // Legacy archives use trailing slash for directories
|
if strings.HasSuffix(hdr.Name, "/") {
|
||||||
|
hdr.Typeflag = TypeDir // Legacy archives use trailing slash for directories
|
||||||
|
} else {
|
||||||
|
hdr.Typeflag = TypeReg
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The extended headers may have updated the size.
|
// The extended headers may have updated the size.
|
||||||
|
|
@ -200,7 +203,7 @@ func (tr *Reader) handleSparseFile(hdr *Header, rawHdr *block) error {
|
||||||
// readGNUSparsePAXHeaders checks the PAX headers for GNU sparse headers.
|
// readGNUSparsePAXHeaders checks the PAX headers for GNU sparse headers.
|
||||||
// If they are found, then this function reads the sparse map and returns it.
|
// If they are found, then this function reads the sparse map and returns it.
|
||||||
// This assumes that 0.0 headers have already been converted to 0.1 headers
|
// This assumes that 0.0 headers have already been converted to 0.1 headers
|
||||||
// by the the PAX header parsing logic.
|
// by the PAX header parsing logic.
|
||||||
func (tr *Reader) readGNUSparsePAXHeaders(hdr *Header) (sparseDatas, error) {
|
func (tr *Reader) readGNUSparsePAXHeaders(hdr *Header) (sparseDatas, error) {
|
||||||
// Identify the version of GNU headers.
|
// Identify the version of GNU headers.
|
||||||
var is1x0 bool
|
var is1x0 bool
|
||||||
|
|
|
||||||
|
|
@ -189,7 +189,7 @@ func TestReader(t *testing.T) {
|
||||||
Gid: 5000,
|
Gid: 5000,
|
||||||
Size: 5,
|
Size: 5,
|
||||||
ModTime: time.Unix(1244593104, 0),
|
ModTime: time.Unix(1244593104, 0),
|
||||||
Typeflag: '\x00',
|
Typeflag: '0',
|
||||||
}, {
|
}, {
|
||||||
Name: "small2.txt",
|
Name: "small2.txt",
|
||||||
Mode: 0444,
|
Mode: 0444,
|
||||||
|
|
@ -197,7 +197,7 @@ func TestReader(t *testing.T) {
|
||||||
Gid: 5000,
|
Gid: 5000,
|
||||||
Size: 11,
|
Size: 11,
|
||||||
ModTime: time.Unix(1244593104, 0),
|
ModTime: time.Unix(1244593104, 0),
|
||||||
Typeflag: '\x00',
|
Typeflag: '0',
|
||||||
}},
|
}},
|
||||||
}, {
|
}, {
|
||||||
file: "testdata/pax.tar",
|
file: "testdata/pax.tar",
|
||||||
|
|
@ -378,9 +378,9 @@ func TestReader(t *testing.T) {
|
||||||
"security.selinux": "unconfined_u:object_r:default_t:s0\x00",
|
"security.selinux": "unconfined_u:object_r:default_t:s0\x00",
|
||||||
},
|
},
|
||||||
PAXRecords: map[string]string{
|
PAXRecords: map[string]string{
|
||||||
"mtime": "1386065770.449252304",
|
"mtime": "1386065770.449252304",
|
||||||
"atime": "1389782991.41987522",
|
"atime": "1389782991.41987522",
|
||||||
"ctime": "1386065770.449252304",
|
"ctime": "1386065770.449252304",
|
||||||
"SCHILY.xattr.security.selinux": "unconfined_u:object_r:default_t:s0\x00",
|
"SCHILY.xattr.security.selinux": "unconfined_u:object_r:default_t:s0\x00",
|
||||||
},
|
},
|
||||||
Format: FormatPAX,
|
Format: FormatPAX,
|
||||||
|
|
@ -534,9 +534,10 @@ func TestReader(t *testing.T) {
|
||||||
// a buggy pre-Go1.8 tar.Writer.
|
// a buggy pre-Go1.8 tar.Writer.
|
||||||
file: "testdata/invalid-go17.tar",
|
file: "testdata/invalid-go17.tar",
|
||||||
headers: []*Header{{
|
headers: []*Header{{
|
||||||
Name: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/foo",
|
Name: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/foo",
|
||||||
Uid: 010000000,
|
Uid: 010000000,
|
||||||
ModTime: time.Unix(0, 0),
|
ModTime: time.Unix(0, 0),
|
||||||
|
Typeflag: '0',
|
||||||
}},
|
}},
|
||||||
}, {
|
}, {
|
||||||
// USTAR archive with a regular entry with non-zero device numbers.
|
// USTAR archive with a regular entry with non-zero device numbers.
|
||||||
|
|
|
||||||
|
|
@ -306,6 +306,7 @@ func TestRoundTrip(t *testing.T) {
|
||||||
ModTime: time.Now().Round(time.Second),
|
ModTime: time.Now().Round(time.Second),
|
||||||
PAXRecords: map[string]string{"uid": "2097152"},
|
PAXRecords: map[string]string{"uid": "2097152"},
|
||||||
Format: FormatPAX,
|
Format: FormatPAX,
|
||||||
|
Typeflag: TypeReg,
|
||||||
}
|
}
|
||||||
if err := tw.WriteHeader(hdr); err != nil {
|
if err := tw.WriteHeader(hdr); err != nil {
|
||||||
t.Fatalf("tw.WriteHeader: %v", err)
|
t.Fatalf("tw.WriteHeader: %v", err)
|
||||||
|
|
|
||||||
BIN
src/archive/tar/testdata/file-and-dir.tar
vendored
Normal file
BIN
src/archive/tar/testdata/file-and-dir.tar
vendored
Normal file
Binary file not shown.
BIN
src/archive/tar/testdata/trailing-slash.tar
vendored
BIN
src/archive/tar/testdata/trailing-slash.tar
vendored
Binary file not shown.
|
|
@ -5,7 +5,6 @@
|
||||||
package tar
|
package tar
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"path"
|
"path"
|
||||||
|
|
@ -71,6 +70,16 @@ func (tw *Writer) WriteHeader(hdr *Header) error {
|
||||||
}
|
}
|
||||||
tw.hdr = *hdr // Shallow copy of Header
|
tw.hdr = *hdr // Shallow copy of Header
|
||||||
|
|
||||||
|
// Avoid usage of the legacy TypeRegA flag, and automatically promote
|
||||||
|
// it to use TypeReg or TypeDir.
|
||||||
|
if tw.hdr.Typeflag == TypeRegA {
|
||||||
|
if strings.HasSuffix(tw.hdr.Name, "/") {
|
||||||
|
tw.hdr.Typeflag = TypeDir
|
||||||
|
} else {
|
||||||
|
tw.hdr.Typeflag = TypeReg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Round ModTime and ignore AccessTime and ChangeTime unless
|
// Round ModTime and ignore AccessTime and ChangeTime unless
|
||||||
// the format is explicitly chosen.
|
// the format is explicitly chosen.
|
||||||
// This ensures nominal usage of WriteHeader (without specifying the format)
|
// This ensures nominal usage of WriteHeader (without specifying the format)
|
||||||
|
|
@ -166,7 +175,7 @@ func (tw *Writer) writePAXHeader(hdr *Header, paxHdrs map[string]string) error {
|
||||||
sort.Strings(keys)
|
sort.Strings(keys)
|
||||||
|
|
||||||
// Write each record to a buffer.
|
// Write each record to a buffer.
|
||||||
var buf bytes.Buffer
|
var buf strings.Builder
|
||||||
for _, k := range keys {
|
for _, k := range keys {
|
||||||
rec, err := formatPAXRecord(k, paxHdrs[k])
|
rec, err := formatPAXRecord(k, paxHdrs[k])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -461,6 +461,15 @@ func TestWriter(t *testing.T) {
|
||||||
testHeader{Header{Name: strings.Repeat("123456789/", 30)}, nil},
|
testHeader{Header{Name: strings.Repeat("123456789/", 30)}, nil},
|
||||||
testClose{nil},
|
testClose{nil},
|
||||||
},
|
},
|
||||||
|
}, {
|
||||||
|
// Automatically promote zero value of Typeflag depending on the name.
|
||||||
|
file: "testdata/file-and-dir.tar",
|
||||||
|
tests: []testFnc{
|
||||||
|
testHeader{Header{Name: "small.txt", Size: 5}, nil},
|
||||||
|
testWrite{"Kilts", 5, nil},
|
||||||
|
testHeader{Header{Name: "dir/"}, nil},
|
||||||
|
testClose{nil},
|
||||||
|
},
|
||||||
}}
|
}}
|
||||||
|
|
||||||
equalError := func(x, y error) bool {
|
equalError := func(x, y error) bool {
|
||||||
|
|
@ -809,8 +818,8 @@ func TestValidTypeflagWithPAXHeader(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to read header: %s", err)
|
t.Fatalf("Failed to read header: %s", err)
|
||||||
}
|
}
|
||||||
if header.Typeflag != 0 {
|
if header.Typeflag != TypeReg {
|
||||||
t.Fatalf("Typeflag should've been 0, found %d", header.Typeflag)
|
t.Fatalf("Typeflag should've been %d, found %d", TypeReg, header.Typeflag)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -366,7 +366,7 @@ parseExtras:
|
||||||
epoch := time.Date(1601, time.January, 1, 0, 0, 0, 0, time.UTC)
|
epoch := time.Date(1601, time.January, 1, 0, 0, 0, 0, time.UTC)
|
||||||
modified = time.Unix(epoch.Unix()+secs, nsecs)
|
modified = time.Unix(epoch.Unix()+secs, nsecs)
|
||||||
}
|
}
|
||||||
case unixExtraID:
|
case unixExtraID, infoZipUnixExtraID:
|
||||||
if len(fieldBuf) < 8 {
|
if len(fieldBuf) < 8 {
|
||||||
continue parseExtras
|
continue parseExtras
|
||||||
}
|
}
|
||||||
|
|
@ -379,12 +379,6 @@ parseExtras:
|
||||||
}
|
}
|
||||||
ts := int64(fieldBuf.uint32()) // ModTime since Unix epoch
|
ts := int64(fieldBuf.uint32()) // ModTime since Unix epoch
|
||||||
modified = time.Unix(ts, 0)
|
modified = time.Unix(ts, 0)
|
||||||
case infoZipUnixExtraID:
|
|
||||||
if len(fieldBuf) < 4 {
|
|
||||||
continue parseExtras
|
|
||||||
}
|
|
||||||
ts := int64(fieldBuf.uint32()) // ModTime since Unix epoch
|
|
||||||
modified = time.Unix(ts, 0)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -414,7 +414,7 @@ var tests = []ZipTest{
|
||||||
Name: "test.txt",
|
Name: "test.txt",
|
||||||
Content: []byte{},
|
Content: []byte{},
|
||||||
Size: 1<<32 - 1,
|
Size: 1<<32 - 1,
|
||||||
Modified: time.Date(2017, 10, 31, 21, 17, 27, 0, timeZone(-7*time.Hour)),
|
Modified: time.Date(2017, 10, 31, 21, 11, 57, 0, timeZone(-7*time.Hour)),
|
||||||
Mode: 0644,
|
Mode: 0644,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,8 @@ const (
|
||||||
type FileHeader struct {
|
type FileHeader struct {
|
||||||
// Name is the name of the file.
|
// Name is the name of the file.
|
||||||
// It must be a relative path, not start with a drive letter (e.g. C:),
|
// It must be a relative path, not start with a drive letter (e.g. C:),
|
||||||
// and must use forward slashes instead of back slashes.
|
// and must use forward slashes instead of back slashes. A trailing slash
|
||||||
|
// indicates that this file is a directory and should have no data.
|
||||||
Name string
|
Name string
|
||||||
|
|
||||||
// Comment is any arbitrary user-defined string shorter than 64KiB.
|
// Comment is any arbitrary user-defined string shorter than 64KiB.
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"hash"
|
"hash"
|
||||||
"hash/crc32"
|
"hash/crc32"
|
||||||
"io"
|
"io"
|
||||||
|
"strings"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -209,7 +210,8 @@ func (w *Writer) Close() error {
|
||||||
// The file contents will be compressed using the Deflate method.
|
// The file contents will be compressed using the Deflate method.
|
||||||
// The name must be a relative path: it must not start with a drive
|
// The name must be a relative path: it must not start with a drive
|
||||||
// letter (e.g. C:) or leading slash, and only forward slashes are
|
// letter (e.g. C:) or leading slash, and only forward slashes are
|
||||||
// allowed.
|
// allowed. To create a directory instead of a file, add a trailing
|
||||||
|
// slash to the name.
|
||||||
// The file's contents must be written to the io.Writer before the next
|
// The file's contents must be written to the io.Writer before the next
|
||||||
// call to Create, CreateHeader, or Close.
|
// call to Create, CreateHeader, or Close.
|
||||||
func (w *Writer) Create(name string) (io.Writer, error) {
|
func (w *Writer) Create(name string) (io.Writer, error) {
|
||||||
|
|
@ -261,8 +263,6 @@ func (w *Writer) CreateHeader(fh *FileHeader) (io.Writer, error) {
|
||||||
return nil, errors.New("archive/zip: invalid duplicate FileHeader")
|
return nil, errors.New("archive/zip: invalid duplicate FileHeader")
|
||||||
}
|
}
|
||||||
|
|
||||||
fh.Flags |= 0x8 // we will write a data descriptor
|
|
||||||
|
|
||||||
// The ZIP format has a sad state of affairs regarding character encoding.
|
// The ZIP format has a sad state of affairs regarding character encoding.
|
||||||
// Officially, the name and comment fields are supposed to be encoded
|
// Officially, the name and comment fields are supposed to be encoded
|
||||||
// in CP-437 (which is mostly compatible with ASCII), unless the UTF-8
|
// in CP-437 (which is mostly compatible with ASCII), unless the UTF-8
|
||||||
|
|
@ -319,35 +319,52 @@ func (w *Writer) CreateHeader(fh *FileHeader) (io.Writer, error) {
|
||||||
fh.Extra = append(fh.Extra, mbuf[:]...)
|
fh.Extra = append(fh.Extra, mbuf[:]...)
|
||||||
}
|
}
|
||||||
|
|
||||||
fw := &fileWriter{
|
var (
|
||||||
zipw: w.cw,
|
ow io.Writer
|
||||||
compCount: &countWriter{w: w.cw},
|
fw *fileWriter
|
||||||
crc32: crc32.NewIEEE(),
|
)
|
||||||
}
|
|
||||||
comp := w.compressor(fh.Method)
|
|
||||||
if comp == nil {
|
|
||||||
return nil, ErrAlgorithm
|
|
||||||
}
|
|
||||||
var err error
|
|
||||||
fw.comp, err = comp(fw.compCount)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
fw.rawCount = &countWriter{w: fw.comp}
|
|
||||||
|
|
||||||
h := &header{
|
h := &header{
|
||||||
FileHeader: fh,
|
FileHeader: fh,
|
||||||
offset: uint64(w.cw.count),
|
offset: uint64(w.cw.count),
|
||||||
}
|
}
|
||||||
w.dir = append(w.dir, h)
|
|
||||||
fw.header = h
|
|
||||||
|
|
||||||
|
if strings.HasSuffix(fh.Name, "/") {
|
||||||
|
// Set the compression method to Store to ensure data length is truly zero,
|
||||||
|
// which the writeHeader method always encodes for the size fields.
|
||||||
|
// This is necessary as most compression formats have non-zero lengths
|
||||||
|
// even when compressing an empty string.
|
||||||
|
fh.Method = Store
|
||||||
|
fh.Flags &^= 0x8 // we will not write a data descriptor
|
||||||
|
|
||||||
|
ow = dirWriter{}
|
||||||
|
} else {
|
||||||
|
fh.Flags |= 0x8 // we will write a data descriptor
|
||||||
|
|
||||||
|
fw = &fileWriter{
|
||||||
|
zipw: w.cw,
|
||||||
|
compCount: &countWriter{w: w.cw},
|
||||||
|
crc32: crc32.NewIEEE(),
|
||||||
|
}
|
||||||
|
comp := w.compressor(fh.Method)
|
||||||
|
if comp == nil {
|
||||||
|
return nil, ErrAlgorithm
|
||||||
|
}
|
||||||
|
var err error
|
||||||
|
fw.comp, err = comp(fw.compCount)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
fw.rawCount = &countWriter{w: fw.comp}
|
||||||
|
fw.header = h
|
||||||
|
ow = fw
|
||||||
|
}
|
||||||
|
w.dir = append(w.dir, h)
|
||||||
if err := writeHeader(w.cw, fh); err != nil {
|
if err := writeHeader(w.cw, fh); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
// If we're creating a directory, fw is nil.
|
||||||
w.last = fw
|
w.last = fw
|
||||||
return fw, nil
|
return ow, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeHeader(w io.Writer, h *FileHeader) error {
|
func writeHeader(w io.Writer, h *FileHeader) error {
|
||||||
|
|
@ -400,6 +417,12 @@ func (w *Writer) compressor(method uint16) Compressor {
|
||||||
return comp
|
return comp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type dirWriter struct{}
|
||||||
|
|
||||||
|
func (dirWriter) Write([]byte) (int, error) {
|
||||||
|
return 0, errors.New("zip: write to directory")
|
||||||
|
}
|
||||||
|
|
||||||
type fileWriter struct {
|
type fileWriter struct {
|
||||||
*header
|
*header
|
||||||
zipw io.Writer
|
zipw io.Writer
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ package zip
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
|
@ -299,6 +300,52 @@ func TestWriterFlush(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestWriterDir(t *testing.T) {
|
||||||
|
w := NewWriter(ioutil.Discard)
|
||||||
|
dw, err := w.Create("dir/")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if _, err := dw.Write([]byte("hello")); err == nil {
|
||||||
|
t.Error("Write to directory: got nil error, want non-nil")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriterDirAttributes(t *testing.T) {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
w := NewWriter(&buf)
|
||||||
|
if _, err := w.Create("dir/"); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := w.Close(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
b := buf.Bytes()
|
||||||
|
|
||||||
|
var sig [4]byte
|
||||||
|
binary.LittleEndian.PutUint32(sig[:], uint32(fileHeaderSignature))
|
||||||
|
|
||||||
|
idx := bytes.Index(b, sig[:])
|
||||||
|
if idx == -1 {
|
||||||
|
t.Fatal("file header not found")
|
||||||
|
}
|
||||||
|
b = b[idx:]
|
||||||
|
|
||||||
|
if !bytes.Equal(b[6:10], []byte{0, 0, 0, 0}) { // FileHeader.Flags: 0, FileHeader.Method: 0
|
||||||
|
t.Errorf("unexpected method and flags: %v", b[6:10])
|
||||||
|
}
|
||||||
|
|
||||||
|
if !bytes.Equal(b[14:26], make([]byte, 12)) { // FileHeader.{CRC32,CompressSize,UncompressedSize} all zero.
|
||||||
|
t.Errorf("unexpected crc, compress and uncompressed size to be 0 was: %v", b[14:26])
|
||||||
|
}
|
||||||
|
|
||||||
|
binary.LittleEndian.PutUint32(sig[:], uint32(dataDescriptorSignature))
|
||||||
|
if bytes.Index(b, sig[:]) != -1 {
|
||||||
|
t.Error("there should be no data descriptor")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func testCreate(t *testing.T, w *Writer, wt *WriteTest) {
|
func testCreate(t *testing.T, w *Writer, wt *WriteTest) {
|
||||||
header := &FileHeader{
|
header := &FileHeader{
|
||||||
Name: wt.Name,
|
Name: wt.Name,
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ import (
|
||||||
"internal/testenv"
|
"internal/testenv"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"runtime"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
@ -140,14 +141,7 @@ func (r *rleBuffer) Write(p []byte) (n int, err error) {
|
||||||
rp = &r.buf[len(r.buf)-1]
|
rp = &r.buf[len(r.buf)-1]
|
||||||
// Fast path, if p is entirely the same byte repeated.
|
// Fast path, if p is entirely the same byte repeated.
|
||||||
if lastByte := rp.b; len(p) > 0 && p[0] == lastByte {
|
if lastByte := rp.b; len(p) > 0 && p[0] == lastByte {
|
||||||
all := true
|
if bytes.Count(p, []byte{lastByte}) == len(p) {
|
||||||
for _, b := range p {
|
|
||||||
if b != lastByte {
|
|
||||||
all = false
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if all {
|
|
||||||
rp.n += int64(len(p))
|
rp.n += int64(len(p))
|
||||||
return len(p), nil
|
return len(p), nil
|
||||||
}
|
}
|
||||||
|
|
@ -165,6 +159,25 @@ func (r *rleBuffer) Write(p []byte) (n int, err error) {
|
||||||
return len(p), nil
|
return len(p), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func min(x, y int) int {
|
||||||
|
if x < y {
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
return y
|
||||||
|
}
|
||||||
|
|
||||||
|
func memset(a []byte, b byte) {
|
||||||
|
if len(a) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Double, until we reach power of 2 >= len(a), same as bytes.Repeat,
|
||||||
|
// but without allocation.
|
||||||
|
a[0] = b
|
||||||
|
for i, l := 1, len(a); i < l; i *= 2 {
|
||||||
|
copy(a[i:], a[:i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (r *rleBuffer) ReadAt(p []byte, off int64) (n int, err error) {
|
func (r *rleBuffer) ReadAt(p []byte, off int64) (n int, err error) {
|
||||||
if len(p) == 0 {
|
if len(p) == 0 {
|
||||||
return
|
return
|
||||||
|
|
@ -176,16 +189,13 @@ func (r *rleBuffer) ReadAt(p []byte, off int64) (n int, err error) {
|
||||||
parts := r.buf[skipParts:]
|
parts := r.buf[skipParts:]
|
||||||
if len(parts) > 0 {
|
if len(parts) > 0 {
|
||||||
skipBytes := off - parts[0].off
|
skipBytes := off - parts[0].off
|
||||||
for len(parts) > 0 {
|
for _, part := range parts {
|
||||||
part := parts[0]
|
repeat := min(int(part.n-skipBytes), len(p)-n)
|
||||||
for i := skipBytes; i < part.n; i++ {
|
memset(p[n:n+repeat], part.b)
|
||||||
if n == len(p) {
|
n += repeat
|
||||||
return
|
if n == len(p) {
|
||||||
}
|
return
|
||||||
p[n] = part.b
|
|
||||||
n++
|
|
||||||
}
|
}
|
||||||
parts = parts[1:]
|
|
||||||
skipBytes = 0
|
skipBytes = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -452,6 +462,9 @@ func suffixIsZip64(t *testing.T, zip sizedReaderAt) bool {
|
||||||
|
|
||||||
// Zip64 is required if the total size of the records is uint32max.
|
// Zip64 is required if the total size of the records is uint32max.
|
||||||
func TestZip64LargeDirectory(t *testing.T) {
|
func TestZip64LargeDirectory(t *testing.T) {
|
||||||
|
if runtime.GOARCH == "wasm" {
|
||||||
|
t.Skip("too slow on wasm")
|
||||||
|
}
|
||||||
if testing.Short() {
|
if testing.Short() {
|
||||||
t.Skip("skipping in short mode")
|
t.Skip("skipping in short mode")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,11 @@ else
|
||||||
rm -rf "pkg/${gohostos}_${gohostarch}" "pkg/tool/${gohostos}_${gohostarch}"
|
rm -rf "pkg/${gohostos}_${gohostarch}" "pkg/tool/${gohostos}_${gohostarch}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
GITREV=$(git rev-parse --short HEAD)
|
if [ "$BOOTSTRAP_FORMAT" = "mintgz" ]; then
|
||||||
|
# Fetch git revision before rm -rf .git.
|
||||||
|
GITREV=$(git rev-parse --short HEAD)
|
||||||
|
fi
|
||||||
|
|
||||||
rm -rf pkg/bootstrap pkg/obj .git
|
rm -rf pkg/bootstrap pkg/obj .git
|
||||||
|
|
||||||
# Support for building minimal tar.gz for the builders.
|
# Support for building minimal tar.gz for the builders.
|
||||||
|
|
|
||||||
|
|
@ -462,6 +462,8 @@ func (b *Reader) ReadString(delim byte) (string, error) {
|
||||||
|
|
||||||
// WriteTo implements io.WriterTo.
|
// WriteTo implements io.WriterTo.
|
||||||
// This may make multiple calls to the Read method of the underlying Reader.
|
// This may make multiple calls to the Read method of the underlying Reader.
|
||||||
|
// If the underlying reader supports the WriteTo method,
|
||||||
|
// this calls the underlying WriteTo without buffering.
|
||||||
func (b *Reader) WriteTo(w io.Writer) (n int64, err error) {
|
func (b *Reader) WriteTo(w io.Writer) (n int64, err error) {
|
||||||
n, err = b.writeBuf(w)
|
n, err = b.writeBuf(w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -684,7 +686,9 @@ func (b *Writer) WriteString(s string) (int, error) {
|
||||||
return nn, nil
|
return nn, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadFrom implements io.ReaderFrom.
|
// ReadFrom implements io.ReaderFrom. If the underlying writer
|
||||||
|
// supports the ReadFrom method, and b has no buffered data yet,
|
||||||
|
// this calls the underlying ReadFrom without buffering.
|
||||||
func (b *Writer) ReadFrom(r io.Reader) (n int64, err error) {
|
func (b *Writer) ReadFrom(r io.Reader) (n int64, err error) {
|
||||||
if b.Buffered() == 0 {
|
if b.Buffered() == 0 {
|
||||||
if w, ok := b.wr.(io.ReaderFrom); ok {
|
if w, ok := b.wr.(io.ReaderFrom); ok {
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
package bytes
|
package bytes
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"internal/bytealg"
|
||||||
"unicode"
|
"unicode"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
)
|
)
|
||||||
|
|
@ -46,12 +47,16 @@ func explode(s []byte, n int) [][]byte {
|
||||||
return a[0:na]
|
return a[0:na]
|
||||||
}
|
}
|
||||||
|
|
||||||
// countGeneric actually implements Count
|
// Count counts the number of non-overlapping instances of sep in s.
|
||||||
func countGeneric(s, sep []byte) int {
|
// If sep is an empty slice, Count returns 1 + the number of UTF-8-encoded code points in s.
|
||||||
|
func Count(s, sep []byte) int {
|
||||||
// special case
|
// special case
|
||||||
if len(sep) == 0 {
|
if len(sep) == 0 {
|
||||||
return utf8.RuneCount(s) + 1
|
return utf8.RuneCount(s) + 1
|
||||||
}
|
}
|
||||||
|
if len(sep) == 1 {
|
||||||
|
return bytealg.Count(s, sep[0])
|
||||||
|
}
|
||||||
n := 0
|
n := 0
|
||||||
for {
|
for {
|
||||||
i := Index(s, sep)
|
i := Index(s, sep)
|
||||||
|
|
@ -800,9 +805,9 @@ func EqualFold(s, t []byte) bool {
|
||||||
tr, sr = sr, tr
|
tr, sr = sr, tr
|
||||||
}
|
}
|
||||||
// Fast check for ASCII.
|
// Fast check for ASCII.
|
||||||
if tr < utf8.RuneSelf && 'A' <= sr && sr <= 'Z' {
|
if tr < utf8.RuneSelf {
|
||||||
// ASCII, and sr is upper case. tr must be lower case.
|
// ASCII only, sr/tr must be upper/lower case
|
||||||
if tr == sr+'a'-'A' {
|
if 'A' <= sr && sr <= 'Z' && tr == sr+'a'-'A' {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
|
|
@ -824,6 +829,92 @@ func EqualFold(s, t []byte) bool {
|
||||||
return len(s) == len(t)
|
return len(s) == len(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Index returns the index of the first instance of sep in s, or -1 if sep is not present in s.
|
||||||
|
func Index(s, sep []byte) int {
|
||||||
|
n := len(sep)
|
||||||
|
switch {
|
||||||
|
case n == 0:
|
||||||
|
return 0
|
||||||
|
case n == 1:
|
||||||
|
return IndexByte(s, sep[0])
|
||||||
|
case n == len(s):
|
||||||
|
if Equal(sep, s) {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
case n > len(s):
|
||||||
|
return -1
|
||||||
|
case n <= bytealg.MaxLen:
|
||||||
|
// Use brute force when s and sep both are small
|
||||||
|
if len(s) <= bytealg.MaxBruteForce {
|
||||||
|
return bytealg.Index(s, sep)
|
||||||
|
}
|
||||||
|
c := sep[0]
|
||||||
|
i := 0
|
||||||
|
t := s[:len(s)-n+1]
|
||||||
|
fails := 0
|
||||||
|
for i < len(t) {
|
||||||
|
if t[i] != c {
|
||||||
|
// IndexByte is faster than bytealg.Index, so use it as long as
|
||||||
|
// we're not getting lots of false positives.
|
||||||
|
o := IndexByte(t[i:], c)
|
||||||
|
if o < 0 {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
i += o
|
||||||
|
}
|
||||||
|
if Equal(s[i:i+n], sep) {
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
fails++
|
||||||
|
i++
|
||||||
|
// Switch to bytealg.Index when IndexByte produces too many false positives.
|
||||||
|
if fails > bytealg.Cutover(i) {
|
||||||
|
r := bytealg.Index(s[i:], sep)
|
||||||
|
if r >= 0 {
|
||||||
|
return r + i
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
c := sep[0]
|
||||||
|
i := 0
|
||||||
|
fails := 0
|
||||||
|
t := s[:len(s)-n+1]
|
||||||
|
for i < len(t) {
|
||||||
|
if t[i] != c {
|
||||||
|
o := IndexByte(t[i:], c)
|
||||||
|
if o < 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
i += o
|
||||||
|
}
|
||||||
|
if Equal(s[i:i+n], sep) {
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
fails++
|
||||||
|
if fails >= 4+i>>4 && i < len(t) {
|
||||||
|
// Give up on IndexByte, it isn't skipping ahead
|
||||||
|
// far enough to be better than Rabin-Karp.
|
||||||
|
// Experiments (using IndexPeriodic) suggest
|
||||||
|
// the cutover is about 16 byte skips.
|
||||||
|
// TODO: if large prefixes of sep are matching
|
||||||
|
// we should cutover at even larger average skips,
|
||||||
|
// because Equal becomes that much more expensive.
|
||||||
|
// This code does not take that effect into account.
|
||||||
|
j := indexRabinKarp(s[i:], sep)
|
||||||
|
if j < 0 {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
return i + j
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
func indexRabinKarp(s, sep []byte) int {
|
func indexRabinKarp(s, sep []byte) int {
|
||||||
// Rabin-Karp search
|
// Rabin-Karp search
|
||||||
hashsep, pow := hashStr(sep)
|
hashsep, pow := hashStr(sep)
|
||||||
|
|
|
||||||
|
|
@ -1,88 +0,0 @@
|
||||||
// Copyright 2016 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 bytes
|
|
||||||
|
|
||||||
import "internal/cpu"
|
|
||||||
|
|
||||||
//go:noescape
|
|
||||||
|
|
||||||
// indexShortStr returns the index of the first instance of c in s, or -1 if c is not present in s.
|
|
||||||
// indexShortStr requires 2 <= len(c) <= shortStringLen
|
|
||||||
func indexShortStr(s, c []byte) int // ../runtime/asm_amd64.s
|
|
||||||
func countByte(s []byte, c byte) int // ../runtime/asm_amd64.s
|
|
||||||
|
|
||||||
var shortStringLen int
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
if cpu.X86.HasAVX2 {
|
|
||||||
shortStringLen = 63
|
|
||||||
} else {
|
|
||||||
shortStringLen = 31
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Index returns the index of the first instance of sep in s, or -1 if sep is not present in s.
|
|
||||||
func Index(s, sep []byte) int {
|
|
||||||
n := len(sep)
|
|
||||||
switch {
|
|
||||||
case n == 0:
|
|
||||||
return 0
|
|
||||||
case n == 1:
|
|
||||||
return IndexByte(s, sep[0])
|
|
||||||
case n == len(s):
|
|
||||||
if Equal(sep, s) {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
case n > len(s):
|
|
||||||
return -1
|
|
||||||
case n <= shortStringLen:
|
|
||||||
// Use brute force when s and sep both are small
|
|
||||||
if len(s) <= 64 {
|
|
||||||
return indexShortStr(s, sep)
|
|
||||||
}
|
|
||||||
c := sep[0]
|
|
||||||
i := 0
|
|
||||||
t := s[:len(s)-n+1]
|
|
||||||
fails := 0
|
|
||||||
for i < len(t) {
|
|
||||||
if t[i] != c {
|
|
||||||
// IndexByte skips 16/32 bytes per iteration,
|
|
||||||
// so it's faster than indexShortStr.
|
|
||||||
o := IndexByte(t[i:], c)
|
|
||||||
if o < 0 {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
i += o
|
|
||||||
}
|
|
||||||
if Equal(s[i:i+n], sep) {
|
|
||||||
return i
|
|
||||||
}
|
|
||||||
fails++
|
|
||||||
i++
|
|
||||||
// Switch to indexShortStr when IndexByte produces too many false positives.
|
|
||||||
// Too many means more that 1 error per 8 characters.
|
|
||||||
// Allow some errors in the beginning.
|
|
||||||
if fails > (i+16)/8 {
|
|
||||||
r := indexShortStr(s[i:], sep)
|
|
||||||
if r >= 0 {
|
|
||||||
return r + i
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
return indexRabinKarp(s, sep)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Count counts the number of non-overlapping instances of sep in s.
|
|
||||||
// If sep is an empty slice, Count returns 1 + the number of UTF-8-encoded code points in s.
|
|
||||||
func Count(s, sep []byte) int {
|
|
||||||
if len(sep) == 1 && cpu.X86.HasPOPCNT {
|
|
||||||
return countByte(s, sep[0])
|
|
||||||
}
|
|
||||||
return countGeneric(s, sep)
|
|
||||||
}
|
|
||||||
|
|
@ -1,68 +0,0 @@
|
||||||
// Copyright 2017 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 bytes
|
|
||||||
|
|
||||||
func countByte(s []byte, c byte) int // bytes_arm64.s
|
|
||||||
|
|
||||||
// Index returns the index of the first instance of sep in s, or -1 if sep is not present in s.
|
|
||||||
func Index(s, sep []byte) int {
|
|
||||||
n := len(sep)
|
|
||||||
switch {
|
|
||||||
case n == 0:
|
|
||||||
return 0
|
|
||||||
case n == 1:
|
|
||||||
return IndexByte(s, sep[0])
|
|
||||||
case n == len(s):
|
|
||||||
if Equal(sep, s) {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
case n > len(s):
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
c := sep[0]
|
|
||||||
i := 0
|
|
||||||
fails := 0
|
|
||||||
t := s[:len(s)-n+1]
|
|
||||||
for i < len(t) {
|
|
||||||
if t[i] != c {
|
|
||||||
o := IndexByte(t[i:], c)
|
|
||||||
if o < 0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
i += o
|
|
||||||
}
|
|
||||||
if Equal(s[i:i+n], sep) {
|
|
||||||
return i
|
|
||||||
}
|
|
||||||
i++
|
|
||||||
fails++
|
|
||||||
if fails >= 4+i>>4 && i < len(t) {
|
|
||||||
// Give up on IndexByte, it isn't skipping ahead
|
|
||||||
// far enough to be better than Rabin-Karp.
|
|
||||||
// Experiments (using IndexPeriodic) suggest
|
|
||||||
// the cutover is about 16 byte skips.
|
|
||||||
// TODO: if large prefixes of sep are matching
|
|
||||||
// we should cutover at even larger average skips,
|
|
||||||
// because Equal becomes that much more expensive.
|
|
||||||
// This code does not take that effect into account.
|
|
||||||
j := indexRabinKarp(s[i:], sep)
|
|
||||||
if j < 0 {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
return i + j
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
|
|
||||||
// Count counts the number of non-overlapping instances of sep in s.
|
|
||||||
// If sep is an empty slice, Count returns 1 + the number of UTF-8-encoded code points in s.
|
|
||||||
func Count(s, sep []byte) int {
|
|
||||||
if len(sep) == 1 {
|
|
||||||
return countByte(s, sep[0])
|
|
||||||
}
|
|
||||||
return countGeneric(s, sep)
|
|
||||||
}
|
|
||||||
|
|
@ -6,19 +6,19 @@ package bytes
|
||||||
|
|
||||||
//go:noescape
|
//go:noescape
|
||||||
|
|
||||||
// IndexByte returns the index of the first instance of c in s, or -1 if c is not present in s.
|
// IndexByte returns the index of the first instance of c in b, or -1 if c is not present in b.
|
||||||
func IndexByte(s []byte, c byte) int // ../runtime/asm_$GOARCH.s
|
func IndexByte(b []byte, c byte) int // in internal/bytealg
|
||||||
|
|
||||||
//go:noescape
|
//go:noescape
|
||||||
|
|
||||||
// Equal returns a boolean reporting whether a and b
|
// Equal returns a boolean reporting whether a and b
|
||||||
// are the same length and contain the same bytes.
|
// are the same length and contain the same bytes.
|
||||||
// A nil argument is equivalent to an empty slice.
|
// A nil argument is equivalent to an empty slice.
|
||||||
func Equal(a, b []byte) bool // ../runtime/asm_$GOARCH.s
|
func Equal(a, b []byte) bool // in internal/bytealg
|
||||||
|
|
||||||
//go:noescape
|
//go:noescape
|
||||||
|
|
||||||
// Compare returns an integer comparing two byte slices lexicographically.
|
// Compare returns an integer comparing two byte slices lexicographically.
|
||||||
// The result will be 0 if a==b, -1 if a < b, and +1 if a > b.
|
// The result will be 0 if a==b, -1 if a < b, and +1 if a > b.
|
||||||
// A nil argument is equivalent to an empty slice.
|
// A nil argument is equivalent to an empty slice.
|
||||||
func Compare(a, b []byte) int // ../runtime/noasm.go or ../runtime/asm_{386,amd64}.s
|
func Compare(a, b []byte) int // in internal/bytealg
|
||||||
|
|
|
||||||
|
|
@ -1,65 +0,0 @@
|
||||||
// Copyright 2015 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build !amd64,!s390x,!arm64
|
|
||||||
|
|
||||||
package bytes
|
|
||||||
|
|
||||||
// Index returns the index of the first instance of sep in s, or -1 if sep is not present in s.
|
|
||||||
func Index(s, sep []byte) int {
|
|
||||||
n := len(sep)
|
|
||||||
switch {
|
|
||||||
case n == 0:
|
|
||||||
return 0
|
|
||||||
case n == 1:
|
|
||||||
return IndexByte(s, sep[0])
|
|
||||||
case n == len(s):
|
|
||||||
if Equal(sep, s) {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
case n > len(s):
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
c := sep[0]
|
|
||||||
i := 0
|
|
||||||
fails := 0
|
|
||||||
t := s[:len(s)-n+1]
|
|
||||||
for i < len(t) {
|
|
||||||
if t[i] != c {
|
|
||||||
o := IndexByte(t[i:], c)
|
|
||||||
if o < 0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
i += o
|
|
||||||
}
|
|
||||||
if Equal(s[i:i+n], sep) {
|
|
||||||
return i
|
|
||||||
}
|
|
||||||
i++
|
|
||||||
fails++
|
|
||||||
if fails >= 4+i>>4 && i < len(t) {
|
|
||||||
// Give up on IndexByte, it isn't skipping ahead
|
|
||||||
// far enough to be better than Rabin-Karp.
|
|
||||||
// Experiments (using IndexPeriodic) suggest
|
|
||||||
// the cutover is about 16 byte skips.
|
|
||||||
// TODO: if large prefixes of sep are matching
|
|
||||||
// we should cutover at even larger average skips,
|
|
||||||
// because Equal becomes that much more expensive.
|
|
||||||
// This code does not take that effect into account.
|
|
||||||
j := indexRabinKarp(s[i:], sep)
|
|
||||||
if j < 0 {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
return i + j
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
|
|
||||||
// Count counts the number of non-overlapping instances of sep in s.
|
|
||||||
// If sep is an empty slice, Count returns 1 + the number of UTF-8-encoded code points in s.
|
|
||||||
func Count(s, sep []byte) int {
|
|
||||||
return countGeneric(s, sep)
|
|
||||||
}
|
|
||||||
|
|
@ -1,86 +0,0 @@
|
||||||
// Copyright 2016 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 bytes
|
|
||||||
|
|
||||||
//go:noescape
|
|
||||||
|
|
||||||
// indexShortStr returns the index of the first instance of sep in s,
|
|
||||||
// or -1 if sep is not present in s.
|
|
||||||
// indexShortStr requires 2 <= len(sep) <= shortStringLen
|
|
||||||
func indexShortStr(s, c []byte) int // ../runtime/asm_s390x.s
|
|
||||||
|
|
||||||
// supportsVX reports whether the vector facility is available.
|
|
||||||
// indexShortStr must not be called if the vector facility is not
|
|
||||||
// available.
|
|
||||||
func supportsVX() bool // ../runtime/asm_s390x.s
|
|
||||||
|
|
||||||
var shortStringLen = -1
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
if supportsVX() {
|
|
||||||
shortStringLen = 64
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Index returns the index of the first instance of sep in s, or -1 if sep is not present in s.
|
|
||||||
func Index(s, sep []byte) int {
|
|
||||||
n := len(sep)
|
|
||||||
switch {
|
|
||||||
case n == 0:
|
|
||||||
return 0
|
|
||||||
case n == 1:
|
|
||||||
return IndexByte(s, sep[0])
|
|
||||||
case n == len(s):
|
|
||||||
if Equal(sep, s) {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
case n > len(s):
|
|
||||||
return -1
|
|
||||||
case n <= shortStringLen:
|
|
||||||
// Use brute force when s and sep both are small
|
|
||||||
if len(s) <= 64 {
|
|
||||||
return indexShortStr(s, sep)
|
|
||||||
}
|
|
||||||
c := sep[0]
|
|
||||||
i := 0
|
|
||||||
t := s[:len(s)-n+1]
|
|
||||||
fails := 0
|
|
||||||
for i < len(t) {
|
|
||||||
if t[i] != c {
|
|
||||||
// IndexByte skips 16/32 bytes per iteration,
|
|
||||||
// so it's faster than indexShortStr.
|
|
||||||
o := IndexByte(t[i:], c)
|
|
||||||
if o < 0 {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
i += o
|
|
||||||
}
|
|
||||||
if Equal(s[i:i+n], sep) {
|
|
||||||
return i
|
|
||||||
}
|
|
||||||
fails++
|
|
||||||
i++
|
|
||||||
// Switch to indexShortStr when IndexByte produces too many false positives.
|
|
||||||
// Too many means more that 1 error per 8 characters.
|
|
||||||
// Allow some errors in the beginning.
|
|
||||||
if fails > (i+16)/8 {
|
|
||||||
r := indexShortStr(s[i:], sep)
|
|
||||||
if r >= 0 {
|
|
||||||
return r + i
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
return indexRabinKarp(s, sep)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Count counts the number of non-overlapping instances of sep in s.
|
|
||||||
// If sep is an empty slice, Count returns 1 + the number of UTF-8-encoded code points in s.
|
|
||||||
func Count(s, sep []byte) int {
|
|
||||||
return countGeneric(s, sep)
|
|
||||||
}
|
|
||||||
|
|
@ -410,10 +410,6 @@ func TestCountByte(t *testing.T) {
|
||||||
if p != j+1 {
|
if p != j+1 {
|
||||||
t.Errorf("TestCountByte.Count(%q, 100) = %d", b[i:i+window], p)
|
t.Errorf("TestCountByte.Count(%q, 100) = %d", b[i:i+window], p)
|
||||||
}
|
}
|
||||||
pGeneric := CountGeneric(b[i:i+window], []byte{100})
|
|
||||||
if pGeneric != j+1 {
|
|
||||||
t.Errorf("TestCountByte.CountGeneric(%q, 100) = %d", b[i:i+window], p)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -461,10 +457,6 @@ func TestCountByteNoMatch(t *testing.T) {
|
||||||
if p != 0 {
|
if p != 0 {
|
||||||
t.Errorf("TestCountByteNoMatch(%q, 0) = %d", b[i:i+window], p)
|
t.Errorf("TestCountByteNoMatch(%q, 0) = %d", b[i:i+window], p)
|
||||||
}
|
}
|
||||||
pGeneric := CountGeneric(b[i:i+window], []byte{0})
|
|
||||||
if pGeneric != 0 {
|
|
||||||
t.Errorf("TestCountByteNoMatch.CountGeneric(%q, 100) = %d", b[i:i+window], p)
|
|
||||||
}
|
|
||||||
for j := 0; j < window; j++ {
|
for j := 0; j < window; j++ {
|
||||||
b[i+j] = byte(0)
|
b[i+j] = byte(0)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,4 +7,3 @@ package bytes
|
||||||
// Export func for testing
|
// Export func for testing
|
||||||
var IndexBytePortable = indexBytePortable
|
var IndexBytePortable = indexBytePortable
|
||||||
var EqualPortable = equalPortable
|
var EqualPortable = equalPortable
|
||||||
var CountGeneric = countGeneric
|
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue