Merge remote-tracking branch 'ethereum/master' into rebase-1.4.4
1
.github/CONTRIBUTING.md
vendored
|
|
@ -1,4 +1,5 @@
|
||||||
If you'd like to contribute to go-expanse please fork, fix, commit and
|
If you'd like to contribute to go-expanse please fork, fix, commit and
|
||||||
|
|
||||||
send a pull request. Commits who do not comply with the coding standards
|
send a pull request. Commits who do not comply with the coding standards
|
||||||
are ignored (use gofmt!). If you send pull requests make absolute sure that you
|
are ignored (use gofmt!). If you send pull requests make absolute sure that you
|
||||||
commit on the `develop` branch and that you do not merge to master.
|
commit on the `develop` branch and that you do not merge to master.
|
||||||
|
|
|
||||||
2
.github/ISSUE_TEMPLATE.md
vendored
|
|
@ -1,6 +1,6 @@
|
||||||
#### System information
|
#### System information
|
||||||
|
|
||||||
Geth version: `geth version`
|
Gexp version: `gexp version`
|
||||||
OS & Version: Windows/Linux/OSX
|
OS & Version: Windows/Linux/OSX
|
||||||
Commit hash : (if `develop`)
|
Commit hash : (if `develop`)
|
||||||
|
|
||||||
|
|
|
||||||
5
.gitignore
vendored
|
|
@ -36,4 +36,7 @@ profile.tmp
|
||||||
profile.cov
|
profile.cov
|
||||||
|
|
||||||
.idea/workspace.xml
|
.idea/workspace.xml
|
||||||
*.idea/
|
*.idea/
|
||||||
|
|
||||||
|
# vagrant
|
||||||
|
.vagrant
|
||||||
|
|
|
||||||
64
.mailmap
|
|
@ -1,61 +1,3 @@
|
||||||
Jeffrey Wilcke <jeffrey@expanse.org>
|
Christopher Franko <chrisjfranko@gmail.com>
|
||||||
Jeffrey Wilcke <jeffrey@expanse.org> <geffobscura@gmail.com>
|
Dan Conway <dan@expanse.tech>
|
||||||
Jeffrey Wilcke <jeffrey@expanse.org> <obscuren@obscura.com>
|
James Clayton <james@expanse.tech>
|
||||||
Jeffrey Wilcke <jeffrey@expanse.org> <obscuren@users.noreply.github.com>
|
|
||||||
|
|
||||||
Viktor Trón <viktor.tron@gmail.com>
|
|
||||||
|
|
||||||
Joseph Goulden <joegoulden@gmail.com>
|
|
||||||
|
|
||||||
Nick Savers <nicksavers@gmail.com>
|
|
||||||
|
|
||||||
Maran Hidskes <maran.hidskes@gmail.com>
|
|
||||||
|
|
||||||
Taylor Gerring <taylor.gerring@gmail.com>
|
|
||||||
Taylor Gerring <taylor.gerring@gmail.com> <taylor.gerring@expanse.org>
|
|
||||||
|
|
||||||
Bas van Kervel <bas@ethdev.com>
|
|
||||||
Bas van Kervel <bas@ethdev.com> <basvankervel@ziggo.nl>
|
|
||||||
Bas van Kervel <bas@ethdev.com> <basvankervel@gmail.com>
|
|
||||||
|
|
||||||
Sven Ehlert <sven@ethdev.com>
|
|
||||||
|
|
||||||
Vitalik Buterin <v@buterin.com>
|
|
||||||
|
|
||||||
Marian Oancea <contact@siteshop.ro>
|
|
||||||
|
|
||||||
Christoph Jentzsch <jentzsch.software@gmail.com>
|
|
||||||
|
|
||||||
Heiko Hees <heiko@heiko.org>
|
|
||||||
|
|
||||||
Alex Leverington <alex@ethdev.com>
|
|
||||||
Alex Leverington <alex@ethdev.com> <subtly@users.noreply.github.com>
|
|
||||||
|
|
||||||
Zsolt Felföldi <zsfelfoldi@gmail.com>
|
|
||||||
|
|
||||||
Gavin Wood <i@gavwood.com>
|
|
||||||
|
|
||||||
Martin Becze <mjbecze@gmail.com>
|
|
||||||
Martin Becze <mjbecze@gmail.com> <wanderer@users.noreply.github.com>
|
|
||||||
|
|
||||||
Dimitry Khokhlov <winsvega@mail.ru>
|
|
||||||
|
|
||||||
Roman Mandeleil <roman.mandeleil@gmail.com>
|
|
||||||
|
|
||||||
Alec Perseghin <aperseghin@gmail.com>
|
|
||||||
|
|
||||||
Alon Muroch <alonmuroch@gmail.com>
|
|
||||||
|
|
||||||
Arkadiy Paronyan <arkadiy@ethdev.com>
|
|
||||||
|
|
||||||
Jae Kwon <jkwon.work@gmail.com>
|
|
||||||
|
|
||||||
Aaron Kumavis <kumavis@users.noreply.github.com>
|
|
||||||
|
|
||||||
Nick Dodson <silentcicero@outlook.com>
|
|
||||||
|
|
||||||
Jason Carver <jacarver@linkedin.com>
|
|
||||||
Jason Carver <jacarver@linkedin.com> <ut96caarrs@snkmail.com>
|
|
||||||
|
|
||||||
Joseph Chow <expanse@outlook.com>
|
|
||||||
Joseph Chow <expanse@outlook.com> ethers <TODO>
|
|
||||||
|
|
|
||||||
17
AUTHORS
|
|
@ -3,22 +3,35 @@
|
||||||
Alex Leverington <alex@ethdev.com>
|
Alex Leverington <alex@ethdev.com>
|
||||||
Alexandre Van de Sande <alex.vandesande@ethdev.com>
|
Alexandre Van de Sande <alex.vandesande@ethdev.com>
|
||||||
Bas van Kervel <bas@ethdev.com>
|
Bas van Kervel <bas@ethdev.com>
|
||||||
|
Christoph Jentzsch <jentzsch.software@gmail.com>
|
||||||
|
Christopher Franko <chrisjfranko@gmail.com>
|
||||||
Daniel A. Nagy <nagy.da@gmail.com>
|
Daniel A. Nagy <nagy.da@gmail.com>
|
||||||
|
Drake Burroughs <wildfyre@hotmail.com>
|
||||||
|
Enrique Fynn <enriquefynn@gmail.com>
|
||||||
Ethan Buchman <ethan@coinculture.info>
|
Ethan Buchman <ethan@coinculture.info>
|
||||||
Fabian Vogelsteller <fabian@frozeman.de>
|
Fabian Vogelsteller <fabian@frozeman.de>
|
||||||
Felix Lange <fjl@twurst.com>
|
Felix Lange <fjl@twurst.com>
|
||||||
Gustav Simonsson <gustav.simonsson@gmail.com>
|
Gustav Simonsson <gustav.simonsson@gmail.com>
|
||||||
|
Isidoro Ghezzi <isidoro.ghezzi@icloud.com>
|
||||||
Jae Kwon <jkwon.work@gmail.com>
|
Jae Kwon <jkwon.work@gmail.com>
|
||||||
Jason Carver <jacarver@linkedin.com>
|
Jason Carver <jacarver@linkedin.com>
|
||||||
Jeffrey Wilcke <jeffrey@expanse.org>
|
Jeff R. Allen <jra@nella.org>
|
||||||
Joseph Chow <expanse@outlook.com>
|
Jeffrey Wilcke <jeffrey@ethereum.org>
|
||||||
|
Joseph Chow <ethereum@outlook.com>
|
||||||
Kobi Gurkan <kobigurk@gmail.com>
|
Kobi Gurkan <kobigurk@gmail.com>
|
||||||
|
Lefteris Karapetsas <lefteris@refu.co>
|
||||||
|
Leif Jurvetson <leijurv@gmail.com>
|
||||||
Maran Hidskes <maran.hidskes@gmail.com>
|
Maran Hidskes <maran.hidskes@gmail.com>
|
||||||
Marek Kotewicz <marek.kotewicz@gmail.com>
|
Marek Kotewicz <marek.kotewicz@gmail.com>
|
||||||
Matthew Wampler-Doty <matthew.wampler.doty@gmail.com>
|
Matthew Wampler-Doty <matthew.wampler.doty@gmail.com>
|
||||||
Nick Dodson <silentcicero@outlook.com>
|
Nick Dodson <silentcicero@outlook.com>
|
||||||
|
Peter Pratscher <pratscher@gmail.com>
|
||||||
Péter Szilágyi <peterke@gmail.com>
|
Péter Szilágyi <peterke@gmail.com>
|
||||||
|
Ramesh Nair <ram@hiddentao.com>
|
||||||
|
Ricardo Catalinas Jiménez <r@untroubled.be>
|
||||||
|
Rémy Roy <remyroy@remyroy.com>
|
||||||
Taylor Gerring <taylor.gerring@gmail.com>
|
Taylor Gerring <taylor.gerring@gmail.com>
|
||||||
Viktor Trón <viktor.tron@gmail.com>
|
Viktor Trón <viktor.tron@gmail.com>
|
||||||
|
Vincent G <caktux@gmail.com>
|
||||||
Vitalik Buterin <v@buterin.com>
|
Vitalik Buterin <v@buterin.com>
|
||||||
Zsolt Felföldi <zsfelfoldi@gmail.com>
|
Zsolt Felföldi <zsfelfoldi@gmail.com>
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ layouts and accessors, or small macros, inline functions and templates
|
||||||
4. Combined Works.
|
4. Combined Works.
|
||||||
|
|
||||||
You may convey a Combined Work under terms of your choice that,
|
You may convey a Combined Work under terms of your choice that,
|
||||||
taken together, effectively do not restrict modification of the
|
taken togexper, effectively do not restrict modification of the
|
||||||
portions of the Library contained in the Combined Work and reverse
|
portions of the Library contained in the Combined Work and reverse
|
||||||
engineering for debugging such modifications, if you also do each of
|
engineering for debugging such modifications, if you also do each of
|
||||||
the following:
|
the following:
|
||||||
|
|
@ -128,7 +128,7 @@ the following:
|
||||||
5. Combined Libraries.
|
5. Combined Libraries.
|
||||||
|
|
||||||
You may place library facilities that are a work based on the
|
You may place library facilities that are a work based on the
|
||||||
Library side by side in a single library together with other library
|
Library side by side in a single library togexper with other library
|
||||||
facilities that are not Applications and are not covered by this
|
facilities that are not Applications and are not covered by this
|
||||||
License, and convey such a combined library under terms of your
|
License, and convey such a combined library under terms of your
|
||||||
choice, if you do both of the following:
|
choice, if you do both of the following:
|
||||||
|
|
|
||||||
270
Godeps/Godeps.json
generated
|
|
@ -1,121 +1,315 @@
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/expanse-project/go-expanse",
|
"ImportPath": "github.com/expanse-project/go-expanse",
|
||||||
"GoVersion": "go1.4",
|
"GoVersion": "go1.5.2",
|
||||||
"Packages": [
|
"Packages": [
|
||||||
"./..."
|
"./..."
|
||||||
],
|
],
|
||||||
"Deps": [
|
"Deps": [
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/Gustav-Simonsson/go-opencl/cl",
|
||||||
|
"Rev": "593e01cfc4f3353585015321e01951d4a907d3ef"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/cespare/cp",
|
||||||
|
"Rev": "165db2f241fd235aec29ba6d9b1ccd5f1c14637c"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/codegangsta/cli",
|
"ImportPath": "github.com/codegangsta/cli",
|
||||||
"Comment": "1.2.0-161-gf445c89",
|
"Comment": "1.2.0-215-g0ab42fd",
|
||||||
"Rev": "f445c894402839580d30de47551cedc152dad814"
|
"Rev": "0ab42fd482c27cf2c95e7794ad3bb2082c2ab2d7"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/davecgh/go-spew/spew",
|
"ImportPath": "github.com/davecgh/go-spew/spew",
|
||||||
"Rev": "3e6e67c4dcea3ac2f25fd4731abc0e1deaf36216"
|
"Rev": "5215b55f46b2b919f50a1df0eaa5886afe4e3b3d"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/expanse-project/ethash",
|
"ImportPath": "github.com/expanse-org/ethash",
|
||||||
"Comment": "v23.1-238-g062e40a",
|
"Comment": "v23.1-245-g25b32de",
|
||||||
"Rev": "fe2794dd2a3b1425dc3e3cc7f15a1dd591422bf1"
|
"Rev": "25b32de0c0271065c28c3719c2bfe86959d72f0c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/fatih/color",
|
"ImportPath": "github.com/fatih/color",
|
||||||
"Comment": "v0.1-5-gf773d4c",
|
"Comment": "v0.1-12-g9aae6aa",
|
||||||
"Rev": "f773d4c806cc8e4a5749d6a35e2a4bbcd71443d6"
|
"Rev": "9aae6aaa22315390f03959adca2c4d395b02fcef"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gizak/termui",
|
"ImportPath": "github.com/gizak/termui",
|
||||||
"Rev": "bab8dce01c193d82bc04888a0a9a7814d505f532"
|
"Rev": "08a5d3f67b7d9ec87830ea39c48e570a1f18531f"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/golang/snappy",
|
||||||
|
"Rev": "799c780093d646c1b79d30894e22512c319fa137"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/hashicorp/golang-lru",
|
"ImportPath": "github.com/hashicorp/golang-lru",
|
||||||
"Rev": "7f9ef20a0256f494e24126014135cf893ab71e9e"
|
"Rev": "a0d98a5f288019575c6d1f4bb1573fef2d1fcdc4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/hashicorp/golang-lru/simplelru",
|
||||||
|
"Rev": "a0d98a5f288019575c6d1f4bb1573fef2d1fcdc4"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/huin/goupnp",
|
"ImportPath": "github.com/huin/goupnp",
|
||||||
"Rev": "90f71cb5dd6d4606388666d2cda4ce2f563d2185"
|
"Rev": "46bde78b11f3f021f2a511df138be9e2fc7506e8"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/huin/goupnp/dcps/internetgateway1",
|
||||||
|
"Rev": "46bde78b11f3f021f2a511df138be9e2fc7506e8"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/huin/goupnp/dcps/internetgateway2",
|
||||||
|
"Rev": "46bde78b11f3f021f2a511df138be9e2fc7506e8"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/huin/goupnp/httpu",
|
||||||
|
"Rev": "46bde78b11f3f021f2a511df138be9e2fc7506e8"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/huin/goupnp/scpd",
|
||||||
|
"Rev": "46bde78b11f3f021f2a511df138be9e2fc7506e8"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/huin/goupnp/soap",
|
||||||
|
"Rev": "46bde78b11f3f021f2a511df138be9e2fc7506e8"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/huin/goupnp/ssdp",
|
||||||
|
"Rev": "46bde78b11f3f021f2a511df138be9e2fc7506e8"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/jackpal/gateway",
|
||||||
|
"Rev": "192609c58b8985e645cbe82ddcb28a4362ca0fdc"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/jackpal/go-nat-pmp",
|
"ImportPath": "github.com/jackpal/go-nat-pmp",
|
||||||
"Rev": "a45aa3d54aef73b504e15eb71bea0e5565b5e6e1"
|
"Rev": "46523a463303c6ede3ddfe45bde1c7ed52ebaacd"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/kardianos/osext",
|
"ImportPath": "github.com/mattn/go-colorable",
|
||||||
"Rev": "ccfcd0245381f0c94c68f50626665eed3c6b726a"
|
"Rev": "9fdad7c47650b7d2e1da50644c1f4ba7f172f252"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/mattn/go-isatty",
|
"ImportPath": "github.com/mattn/go-isatty",
|
||||||
"Rev": "7fcbc72f853b92b5720db4a6b8482be612daef24"
|
"Rev": "56b76bdf51f7708750eac80fa38b952bb9f32639"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/mattn/go-runewidth",
|
"ImportPath": "github.com/mattn/go-runewidth",
|
||||||
"Comment": "travisish-33-g5890272",
|
"Comment": "travisish-44-ge882a96",
|
||||||
"Rev": "5890272cd41c5103531cd7b79e428d99c9e97f76"
|
"Rev": "e882a96ec18dd43fa283187b66af74497c9101c0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/microsoft/go-winio",
|
||||||
|
"Comment": "v0.2.0",
|
||||||
|
"Rev": "9e2895e5f6c3f16473b91d37fae6e89990a4520c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/nsf/termbox-go",
|
"ImportPath": "github.com/nsf/termbox-go",
|
||||||
"Rev": "675ffd907b7401b8a709a5ef2249978af5616bb2"
|
"Rev": "362329b0aa6447eadd52edd8d660ec1dff470295"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/pborman/uuid",
|
"ImportPath": "github.com/pborman/uuid",
|
||||||
"Rev": "cccd189d45f7ac3368a0d127efb7f4d08ae0b655"
|
"Comment": "v1.0-6-g0f1a469",
|
||||||
|
"Rev": "0f1a46960a86dcdf5dd30d3e6568a497a997909f"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/peterh/liner",
|
"ImportPath": "github.com/peterh/liner",
|
||||||
"Rev": "29f6a646557d83e2b6e9ba05c45fbea9c006dbe8"
|
"Rev": "ad1edfd30321d8f006ccf05f1e0524adeb943060"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/rcrowley/go-metrics",
|
"ImportPath": "github.com/rcrowley/go-metrics",
|
||||||
"Rev": "a5cfc242a56ba7fa70b785f678d6214837bf93b9"
|
"Rev": "51425a2415d21afadfd55cd93432c0bc69e9598d"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/rjeczalik/notify",
|
||||||
|
"Rev": "5dd6205716539662f8f14ab513552b41eab69d5d"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/robertkrimen/otto",
|
"ImportPath": "github.com/robertkrimen/otto",
|
||||||
"Rev": "dea31a3d392779af358ec41f77a07fcc7e9d04ba"
|
"Rev": "53221230c215611a90762720c9042ac782ef74ee"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/robertkrimen/otto/ast",
|
||||||
|
"Rev": "53221230c215611a90762720c9042ac782ef74ee"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/robertkrimen/otto/dbg",
|
||||||
|
"Rev": "53221230c215611a90762720c9042ac782ef74ee"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/robertkrimen/otto/file",
|
||||||
|
"Rev": "53221230c215611a90762720c9042ac782ef74ee"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/robertkrimen/otto/parser",
|
||||||
|
"Rev": "53221230c215611a90762720c9042ac782ef74ee"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/robertkrimen/otto/registry",
|
||||||
|
"Rev": "53221230c215611a90762720c9042ac782ef74ee"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/robertkrimen/otto/token",
|
||||||
|
"Rev": "53221230c215611a90762720c9042ac782ef74ee"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/rs/cors",
|
"ImportPath": "github.com/rs/cors",
|
||||||
"Rev": "6e0c3cb65fc0fdb064c743d176a620e3ca446dfb"
|
"Rev": "5950cf11d77f8a61b432a25dd4d444b4ced01379"
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/shiena/ansicolor",
|
|
||||||
"Rev": "a5e2b567a4dd6cc74545b8a4f27c9d63b9e7735b"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/syndtr/goleveldb/leveldb",
|
"ImportPath": "github.com/syndtr/goleveldb/leveldb",
|
||||||
"Rev": "4875955338b0a434238a31165cb87255ab6e9e4a"
|
"Rev": "917f41c560270110ceb73c5b38be2a9127387071"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/syndtr/gosnappy/snappy",
|
"ImportPath": "github.com/syndtr/goleveldb/leveldb/cache",
|
||||||
"Rev": "156a073208e131d7d2e212cb749feae7c339e846"
|
"Rev": "917f41c560270110ceb73c5b38be2a9127387071"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/syndtr/goleveldb/leveldb/comparer",
|
||||||
|
"Rev": "917f41c560270110ceb73c5b38be2a9127387071"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/syndtr/goleveldb/leveldb/errors",
|
||||||
|
"Rev": "917f41c560270110ceb73c5b38be2a9127387071"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/syndtr/goleveldb/leveldb/filter",
|
||||||
|
"Rev": "917f41c560270110ceb73c5b38be2a9127387071"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/syndtr/goleveldb/leveldb/iterator",
|
||||||
|
"Rev": "917f41c560270110ceb73c5b38be2a9127387071"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/syndtr/goleveldb/leveldb/journal",
|
||||||
|
"Rev": "917f41c560270110ceb73c5b38be2a9127387071"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/syndtr/goleveldb/leveldb/memdb",
|
||||||
|
"Rev": "917f41c560270110ceb73c5b38be2a9127387071"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/syndtr/goleveldb/leveldb/opt",
|
||||||
|
"Rev": "917f41c560270110ceb73c5b38be2a9127387071"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/syndtr/goleveldb/leveldb/storage",
|
||||||
|
"Rev": "917f41c560270110ceb73c5b38be2a9127387071"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/syndtr/goleveldb/leveldb/table",
|
||||||
|
"Rev": "917f41c560270110ceb73c5b38be2a9127387071"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/syndtr/goleveldb/leveldb/util",
|
||||||
|
"Rev": "917f41c560270110ceb73c5b38be2a9127387071"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "golang.org/x/crypto/pbkdf2",
|
"ImportPath": "golang.org/x/crypto/pbkdf2",
|
||||||
"Rev": "4ed45ec682102c643324fae5dff8dab085b6c300"
|
"Rev": "1f22c0103821b9390939b6776727195525381532"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "golang.org/x/crypto/ripemd160",
|
"ImportPath": "golang.org/x/crypto/ripemd160",
|
||||||
"Rev": "4ed45ec682102c643324fae5dff8dab085b6c300"
|
"Rev": "1f22c0103821b9390939b6776727195525381532"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "golang.org/x/crypto/scrypt",
|
"ImportPath": "golang.org/x/crypto/scrypt",
|
||||||
"Rev": "4ed45ec682102c643324fae5dff8dab085b6c300"
|
"Rev": "1f22c0103821b9390939b6776727195525381532"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "golang.org/x/net/context",
|
||||||
|
"Rev": "8968c61983e8f51a91b8c0ef25bf739278c89634"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "golang.org/x/net/html",
|
"ImportPath": "golang.org/x/net/html",
|
||||||
"Rev": "e0403b4e005737430c05a57aac078479844f919c"
|
"Rev": "8968c61983e8f51a91b8c0ef25bf739278c89634"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "golang.org/x/net/html/atom",
|
||||||
|
"Rev": "8968c61983e8f51a91b8c0ef25bf739278c89634"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "golang.org/x/net/html/charset",
|
||||||
|
"Rev": "8968c61983e8f51a91b8c0ef25bf739278c89634"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "golang.org/x/net/websocket",
|
||||||
|
"Rev": "8968c61983e8f51a91b8c0ef25bf739278c89634"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "golang.org/x/sys/unix",
|
||||||
|
"Rev": "50c6bc5e4292a1d4e65c6e9be5f53be28bcbe28e"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "golang.org/x/text/encoding",
|
"ImportPath": "golang.org/x/text/encoding",
|
||||||
"Rev": "c93e7c9fff19fb9139b5ab04ce041833add0134e"
|
"Rev": "09761194ac5034a97b2bfad4f5b896b0ac350b3e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "golang.org/x/text/encoding/charmap",
|
||||||
|
"Rev": "09761194ac5034a97b2bfad4f5b896b0ac350b3e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "golang.org/x/text/encoding/htmlindex",
|
||||||
|
"Rev": "09761194ac5034a97b2bfad4f5b896b0ac350b3e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "golang.org/x/text/encoding/internal",
|
||||||
|
"Rev": "09761194ac5034a97b2bfad4f5b896b0ac350b3e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "golang.org/x/text/encoding/internal/identifier",
|
||||||
|
"Rev": "09761194ac5034a97b2bfad4f5b896b0ac350b3e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "golang.org/x/text/encoding/japanese",
|
||||||
|
"Rev": "09761194ac5034a97b2bfad4f5b896b0ac350b3e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "golang.org/x/text/encoding/korean",
|
||||||
|
"Rev": "09761194ac5034a97b2bfad4f5b896b0ac350b3e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "golang.org/x/text/encoding/simplifiedchinese",
|
||||||
|
"Rev": "09761194ac5034a97b2bfad4f5b896b0ac350b3e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "golang.org/x/text/encoding/traditionalchinese",
|
||||||
|
"Rev": "09761194ac5034a97b2bfad4f5b896b0ac350b3e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "golang.org/x/text/encoding/unicode",
|
||||||
|
"Rev": "09761194ac5034a97b2bfad4f5b896b0ac350b3e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "golang.org/x/text/internal/tag",
|
||||||
|
"Rev": "09761194ac5034a97b2bfad4f5b896b0ac350b3e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "golang.org/x/text/internal/utf8internal",
|
||||||
|
"Rev": "09761194ac5034a97b2bfad4f5b896b0ac350b3e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "golang.org/x/text/language",
|
||||||
|
"Rev": "09761194ac5034a97b2bfad4f5b896b0ac350b3e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "golang.org/x/text/runes",
|
||||||
|
"Rev": "09761194ac5034a97b2bfad4f5b896b0ac350b3e"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "golang.org/x/text/transform",
|
"ImportPath": "golang.org/x/text/transform",
|
||||||
"Rev": "c93e7c9fff19fb9139b5ab04ce041833add0134e"
|
"Rev": "09761194ac5034a97b2bfad4f5b896b0ac350b3e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "golang.org/x/tools/go/ast/astutil",
|
||||||
|
"Rev": "758728c4b28cfbac299730969ef8f655c4761283"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "golang.org/x/tools/imports",
|
||||||
|
"Rev": "758728c4b28cfbac299730969ef8f655c4761283"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "gopkg.in/check.v1",
|
"ImportPath": "gopkg.in/check.v1",
|
||||||
"Rev": "64131543e7896d5bcc6bd5a76287eb75ea96c673"
|
"Rev": "4f90aeace3a26ad7021961c297b22c42160c7b25"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "gopkg.in/fatih/set.v0",
|
"ImportPath": "gopkg.in/fatih/set.v0",
|
||||||
|
|
|
||||||
254
Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/cl_test.go
generated
vendored
|
|
@ -1,254 +0,0 @@
|
||||||
package cl
|
|
||||||
|
|
||||||
import (
|
|
||||||
"math/rand"
|
|
||||||
"reflect"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
var kernelSource = `
|
|
||||||
__kernel void square(
|
|
||||||
__global float* input,
|
|
||||||
__global float* output,
|
|
||||||
const unsigned int count)
|
|
||||||
{
|
|
||||||
int i = get_global_id(0);
|
|
||||||
if(i < count)
|
|
||||||
output[i] = input[i] * input[i];
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
func getObjectStrings(object interface{}) map[string]string {
|
|
||||||
v := reflect.ValueOf(object)
|
|
||||||
t := reflect.TypeOf(object)
|
|
||||||
|
|
||||||
strs := make(map[string]string)
|
|
||||||
|
|
||||||
numMethods := t.NumMethod()
|
|
||||||
for i := 0; i < numMethods; i++ {
|
|
||||||
method := t.Method(i)
|
|
||||||
if method.Type.NumIn() == 1 && method.Type.NumOut() == 1 && method.Type.Out(0).Kind() == reflect.String {
|
|
||||||
// this is a string-returning method with (presumably) only a pointer receiver parameter
|
|
||||||
// call it
|
|
||||||
outs := v.Method(i).Call([]reflect.Value{})
|
|
||||||
// put the result in our map
|
|
||||||
strs[method.Name] = (outs[0].Interface()).(string)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return strs
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPlatformStringsContainNoNULs(t *testing.T) {
|
|
||||||
platforms, err := GetPlatforms()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Failed to get platforms: %+v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, p := range platforms {
|
|
||||||
for key, value := range getObjectStrings(p) {
|
|
||||||
if strings.Contains(value, "\x00") {
|
|
||||||
t.Fatalf("platform string %q = %+q contains NUL", key, value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDeviceStringsContainNoNULs(t *testing.T) {
|
|
||||||
platforms, err := GetPlatforms()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Failed to get platforms: %+v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, p := range platforms {
|
|
||||||
devs, err := p.GetDevices(DeviceTypeAll)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Failed to get devices for platform %q: %+v", p.Name(), err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, d := range devs {
|
|
||||||
for key, value := range getObjectStrings(d) {
|
|
||||||
if strings.Contains(value, "\x00") {
|
|
||||||
t.Fatalf("device string %q = %+q contains NUL", key, value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHello(t *testing.T) {
|
|
||||||
var data [1024]float32
|
|
||||||
for i := 0; i < len(data); i++ {
|
|
||||||
data[i] = rand.Float32()
|
|
||||||
}
|
|
||||||
|
|
||||||
platforms, err := GetPlatforms()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Failed to get platforms: %+v", err)
|
|
||||||
}
|
|
||||||
for i, p := range platforms {
|
|
||||||
t.Logf("Platform %d:", i)
|
|
||||||
t.Logf(" Name: %s", p.Name())
|
|
||||||
t.Logf(" Vendor: %s", p.Vendor())
|
|
||||||
t.Logf(" Profile: %s", p.Profile())
|
|
||||||
t.Logf(" Version: %s", p.Version())
|
|
||||||
t.Logf(" Extensions: %s", p.Extensions())
|
|
||||||
}
|
|
||||||
platform := platforms[0]
|
|
||||||
|
|
||||||
devices, err := platform.GetDevices(DeviceTypeAll)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Failed to get devices: %+v", err)
|
|
||||||
}
|
|
||||||
if len(devices) == 0 {
|
|
||||||
t.Fatalf("GetDevices returned no devices")
|
|
||||||
}
|
|
||||||
deviceIndex := -1
|
|
||||||
for i, d := range devices {
|
|
||||||
if deviceIndex < 0 && d.Type() == DeviceTypeGPU {
|
|
||||||
deviceIndex = i
|
|
||||||
}
|
|
||||||
t.Logf("Device %d (%s): %s", i, d.Type(), d.Name())
|
|
||||||
t.Logf(" Address Bits: %d", d.AddressBits())
|
|
||||||
t.Logf(" Available: %+v", d.Available())
|
|
||||||
// t.Logf(" Built-In Kernels: %s", d.BuiltInKernels())
|
|
||||||
t.Logf(" Compiler Available: %+v", d.CompilerAvailable())
|
|
||||||
t.Logf(" Double FP Config: %s", d.DoubleFPConfig())
|
|
||||||
t.Logf(" Driver Version: %s", d.DriverVersion())
|
|
||||||
t.Logf(" Error Correction Supported: %+v", d.ErrorCorrectionSupport())
|
|
||||||
t.Logf(" Execution Capabilities: %s", d.ExecutionCapabilities())
|
|
||||||
t.Logf(" Extensions: %s", d.Extensions())
|
|
||||||
t.Logf(" Global Memory Cache Type: %s", d.GlobalMemCacheType())
|
|
||||||
t.Logf(" Global Memory Cacheline Size: %d KB", d.GlobalMemCachelineSize()/1024)
|
|
||||||
t.Logf(" Global Memory Size: %d MB", d.GlobalMemSize()/(1024*1024))
|
|
||||||
t.Logf(" Half FP Config: %s", d.HalfFPConfig())
|
|
||||||
t.Logf(" Host Unified Memory: %+v", d.HostUnifiedMemory())
|
|
||||||
t.Logf(" Image Support: %+v", d.ImageSupport())
|
|
||||||
t.Logf(" Image2D Max Dimensions: %d x %d", d.Image2DMaxWidth(), d.Image2DMaxHeight())
|
|
||||||
t.Logf(" Image3D Max Dimenionns: %d x %d x %d", d.Image3DMaxWidth(), d.Image3DMaxHeight(), d.Image3DMaxDepth())
|
|
||||||
// t.Logf(" Image Max Buffer Size: %d", d.ImageMaxBufferSize())
|
|
||||||
// t.Logf(" Image Max Array Size: %d", d.ImageMaxArraySize())
|
|
||||||
// t.Logf(" Linker Available: %+v", d.LinkerAvailable())
|
|
||||||
t.Logf(" Little Endian: %+v", d.EndianLittle())
|
|
||||||
t.Logf(" Local Mem Size Size: %d KB", d.LocalMemSize()/1024)
|
|
||||||
t.Logf(" Local Mem Type: %s", d.LocalMemType())
|
|
||||||
t.Logf(" Max Clock Frequency: %d", d.MaxClockFrequency())
|
|
||||||
t.Logf(" Max Compute Units: %d", d.MaxComputeUnits())
|
|
||||||
t.Logf(" Max Constant Args: %d", d.MaxConstantArgs())
|
|
||||||
t.Logf(" Max Constant Buffer Size: %d KB", d.MaxConstantBufferSize()/1024)
|
|
||||||
t.Logf(" Max Mem Alloc Size: %d KB", d.MaxMemAllocSize()/1024)
|
|
||||||
t.Logf(" Max Parameter Size: %d", d.MaxParameterSize())
|
|
||||||
t.Logf(" Max Read-Image Args: %d", d.MaxReadImageArgs())
|
|
||||||
t.Logf(" Max Samplers: %d", d.MaxSamplers())
|
|
||||||
t.Logf(" Max Work Group Size: %d", d.MaxWorkGroupSize())
|
|
||||||
t.Logf(" Max Work Item Dimensions: %d", d.MaxWorkItemDimensions())
|
|
||||||
t.Logf(" Max Work Item Sizes: %d", d.MaxWorkItemSizes())
|
|
||||||
t.Logf(" Max Write-Image Args: %d", d.MaxWriteImageArgs())
|
|
||||||
t.Logf(" Memory Base Address Alignment: %d", d.MemBaseAddrAlign())
|
|
||||||
t.Logf(" Native Vector Width Char: %d", d.NativeVectorWidthChar())
|
|
||||||
t.Logf(" Native Vector Width Short: %d", d.NativeVectorWidthShort())
|
|
||||||
t.Logf(" Native Vector Width Int: %d", d.NativeVectorWidthInt())
|
|
||||||
t.Logf(" Native Vector Width Long: %d", d.NativeVectorWidthLong())
|
|
||||||
t.Logf(" Native Vector Width Float: %d", d.NativeVectorWidthFloat())
|
|
||||||
t.Logf(" Native Vector Width Double: %d", d.NativeVectorWidthDouble())
|
|
||||||
t.Logf(" Native Vector Width Half: %d", d.NativeVectorWidthHalf())
|
|
||||||
t.Logf(" OpenCL C Version: %s", d.OpenCLCVersion())
|
|
||||||
// t.Logf(" Parent Device: %+v", d.ParentDevice())
|
|
||||||
t.Logf(" Profile: %s", d.Profile())
|
|
||||||
t.Logf(" Profiling Timer Resolution: %d", d.ProfilingTimerResolution())
|
|
||||||
t.Logf(" Vendor: %s", d.Vendor())
|
|
||||||
t.Logf(" Version: %s", d.Version())
|
|
||||||
}
|
|
||||||
if deviceIndex < 0 {
|
|
||||||
deviceIndex = 0
|
|
||||||
}
|
|
||||||
device := devices[deviceIndex]
|
|
||||||
t.Logf("Using device %d", deviceIndex)
|
|
||||||
context, err := CreateContext([]*Device{device})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("CreateContext failed: %+v", err)
|
|
||||||
}
|
|
||||||
// imageFormats, err := context.GetSupportedImageFormats(0, MemObjectTypeImage2D)
|
|
||||||
// if err != nil {
|
|
||||||
// t.Fatalf("GetSupportedImageFormats failed: %+v", err)
|
|
||||||
// }
|
|
||||||
// t.Logf("Supported image formats: %+v", imageFormats)
|
|
||||||
queue, err := context.CreateCommandQueue(device, 0)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("CreateCommandQueue failed: %+v", err)
|
|
||||||
}
|
|
||||||
program, err := context.CreateProgramWithSource([]string{kernelSource})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("CreateProgramWithSource failed: %+v", err)
|
|
||||||
}
|
|
||||||
if err := program.BuildProgram(nil, ""); err != nil {
|
|
||||||
t.Fatalf("BuildProgram failed: %+v", err)
|
|
||||||
}
|
|
||||||
kernel, err := program.CreateKernel("square")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("CreateKernel failed: %+v", err)
|
|
||||||
}
|
|
||||||
for i := 0; i < 3; i++ {
|
|
||||||
name, err := kernel.ArgName(i)
|
|
||||||
if err == ErrUnsupported {
|
|
||||||
break
|
|
||||||
} else if err != nil {
|
|
||||||
t.Errorf("GetKernelArgInfo for name failed: %+v", err)
|
|
||||||
break
|
|
||||||
} else {
|
|
||||||
t.Logf("Kernel arg %d: %s", i, name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
input, err := context.CreateEmptyBuffer(MemReadOnly, 4*len(data))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("CreateBuffer failed for input: %+v", err)
|
|
||||||
}
|
|
||||||
output, err := context.CreateEmptyBuffer(MemReadOnly, 4*len(data))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("CreateBuffer failed for output: %+v", err)
|
|
||||||
}
|
|
||||||
if _, err := queue.EnqueueWriteBufferFloat32(input, true, 0, data[:], nil); err != nil {
|
|
||||||
t.Fatalf("EnqueueWriteBufferFloat32 failed: %+v", err)
|
|
||||||
}
|
|
||||||
if err := kernel.SetArgs(input, output, uint32(len(data))); err != nil {
|
|
||||||
t.Fatalf("SetKernelArgs failed: %+v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
local, err := kernel.WorkGroupSize(device)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("WorkGroupSize failed: %+v", err)
|
|
||||||
}
|
|
||||||
t.Logf("Work group size: %d", local)
|
|
||||||
size, _ := kernel.PreferredWorkGroupSizeMultiple(nil)
|
|
||||||
t.Logf("Preferred Work Group Size Multiple: %d", size)
|
|
||||||
|
|
||||||
global := len(data)
|
|
||||||
d := len(data) % local
|
|
||||||
if d != 0 {
|
|
||||||
global += local - d
|
|
||||||
}
|
|
||||||
if _, err := queue.EnqueueNDRangeKernel(kernel, nil, []int{global}, []int{local}, nil); err != nil {
|
|
||||||
t.Fatalf("EnqueueNDRangeKernel failed: %+v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := queue.Finish(); err != nil {
|
|
||||||
t.Fatalf("Finish failed: %+v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
results := make([]float32, len(data))
|
|
||||||
if _, err := queue.EnqueueReadBufferFloat32(output, true, 0, results, nil); err != nil {
|
|
||||||
t.Fatalf("EnqueueReadBufferFloat32 failed: %+v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
correct := 0
|
|
||||||
for i, v := range data {
|
|
||||||
if results[i] == v*v {
|
|
||||||
correct++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if correct != len(data) {
|
|
||||||
t.Fatalf("%d/%d correct values", correct, len(data))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
19
Godeps/_workspace/src/github.com/cespare/cp/LICENSE.txt
generated
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
Copyright (c) 2015 Caleb Spare
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
9
Godeps/_workspace/src/github.com/cespare/cp/README.md
generated
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
# cp
|
||||||
|
|
||||||
|
[](https://godoc.org/github.com/cespare/cp)
|
||||||
|
|
||||||
|
cp is a small Go package for copying files and directories.
|
||||||
|
|
||||||
|
The API may change because I want to add some options in the future (for merging with existing dirs).
|
||||||
|
|
||||||
|
It does not currently handle Windows specifically (I think it may require some special treatment).
|
||||||
58
Godeps/_workspace/src/github.com/cespare/cp/cp.go
generated
vendored
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
// Package cp offers simple file and directory copying for Go.
|
||||||
|
package cp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var errCopyFileWithDir = errors.New("dir argument to CopyFile")
|
||||||
|
|
||||||
|
// CopyFile copies the file with path src to dst. The new file must not exist.
|
||||||
|
// It is created with the same permissions as src.
|
||||||
|
func CopyFile(dst, src string) error {
|
||||||
|
rf, err := os.Open(src)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer rf.Close()
|
||||||
|
rstat, err := rf.Stat()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if rstat.IsDir() {
|
||||||
|
return errCopyFileWithDir
|
||||||
|
}
|
||||||
|
|
||||||
|
wf, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_EXCL, rstat.Mode())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err := io.Copy(wf, rf); err != nil {
|
||||||
|
wf.Close()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return wf.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyAll copies the file or (recursively) the directory at src to dst.
|
||||||
|
// Permissions are preserved. dst must not already exist.
|
||||||
|
func CopyAll(dst, src string) error {
|
||||||
|
return filepath.Walk(src, makeWalkFn(dst, src))
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeWalkFn(dst, src string) filepath.WalkFunc {
|
||||||
|
return func(path string, info os.FileInfo, err error) error {
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
dstPath := filepath.Join(dst, strings.TrimPrefix(path, src))
|
||||||
|
if info.IsDir() {
|
||||||
|
return os.Mkdir(dstPath, info.Mode())
|
||||||
|
}
|
||||||
|
return CopyFile(dstPath, path)
|
||||||
|
}
|
||||||
|
}
|
||||||
6
Godeps/_workspace/src/github.com/codegangsta/cli/.travis.yml
generated
vendored
|
|
@ -7,6 +7,12 @@ go:
|
||||||
- 1.2.2
|
- 1.2.2
|
||||||
- 1.3.3
|
- 1.3.3
|
||||||
- 1.4.2
|
- 1.4.2
|
||||||
|
- 1.5.1
|
||||||
|
- tip
|
||||||
|
|
||||||
|
matrix:
|
||||||
|
allow_failures:
|
||||||
|
- go: tip
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- go vet ./...
|
- go vet ./...
|
||||||
|
|
|
||||||
45
Godeps/_workspace/src/github.com/codegangsta/cli/README.md
generated
vendored
|
|
@ -1,16 +1,19 @@
|
||||||
[](http://gocover.io/github.com/codegangsta/cli)
|
[](http://gocover.io/github.com/codegangsta/cli)
|
||||||
[](https://travis-ci.org/codegangsta/cli)
|
[](https://travis-ci.org/codegangsta/cli)
|
||||||
[](https://godoc.org/github.com/codegangsta/cli)
|
[](https://godoc.org/github.com/codegangsta/cli)
|
||||||
|
|
||||||
# cli.go
|
# cli.go
|
||||||
|
|
||||||
`cli.go` is simple, fast, and fun package for building command line apps in Go. The goal is to enable developers to write fast and distributable command line applications in an expressive way.
|
`cli.go` is simple, fast, and fun package for building command line apps in Go. The goal is to enable developers to write fast and distributable command line applications in an expressive way.
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
Command line apps are usually so tiny that there is absolutely no reason why your code should *not* be self-documenting. Things like generating help text and parsing command flags/options should not hinder productivity when writing a command line app.
|
Command line apps are usually so tiny that there is absolutely no reason why your code should *not* be self-documenting. Things like generating help text and parsing command flags/options should not hinder productivity when writing a command line app.
|
||||||
|
|
||||||
**This is where `cli.go` comes into play.** `cli.go` makes command line programming fun, organized, and expressive!
|
**This is where `cli.go` comes into play.** `cli.go` makes command line programming fun, organized, and expressive!
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
Make sure you have a working Go environment (go 1.1+ is *required*). [See the install instructions](http://golang.org/doc/install.html).
|
Make sure you have a working Go environment (go 1.1+ is *required*). [See the install instructions](http://golang.org/doc/install.html).
|
||||||
|
|
||||||
To install `cli.go`, simply run:
|
To install `cli.go`, simply run:
|
||||||
|
|
@ -24,6 +27,7 @@ export PATH=$PATH:$GOPATH/bin
|
||||||
```
|
```
|
||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
One of the philosophies behind `cli.go` is that an API should be playful and full of discovery. So a `cli.go` app can be as little as one line of code in `main()`.
|
One of the philosophies behind `cli.go` is that an API should be playful and full of discovery. So a `cli.go` app can be as little as one line of code in `main()`.
|
||||||
|
|
||||||
``` go
|
``` go
|
||||||
|
|
@ -123,6 +127,7 @@ GLOBAL OPTIONS
|
||||||
```
|
```
|
||||||
|
|
||||||
### Arguments
|
### Arguments
|
||||||
|
|
||||||
You can lookup arguments by calling the `Args` function on `cli.Context`.
|
You can lookup arguments by calling the `Args` function on `cli.Context`.
|
||||||
|
|
||||||
``` go
|
``` go
|
||||||
|
|
@ -134,7 +139,9 @@ app.Action = func(c *cli.Context) {
|
||||||
```
|
```
|
||||||
|
|
||||||
### Flags
|
### Flags
|
||||||
|
|
||||||
Setting and querying flags is simple.
|
Setting and querying flags is simple.
|
||||||
|
|
||||||
``` go
|
``` go
|
||||||
...
|
...
|
||||||
app.Flags = []cli.Flag {
|
app.Flags = []cli.Flag {
|
||||||
|
|
@ -158,6 +165,33 @@ app.Action = func(c *cli.Context) {
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
You can also set a destination variable for a flag, to which the content will be scanned.
|
||||||
|
|
||||||
|
``` go
|
||||||
|
...
|
||||||
|
var language string
|
||||||
|
app.Flags = []cli.Flag {
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "lang",
|
||||||
|
Value: "english",
|
||||||
|
Usage: "language for the greeting",
|
||||||
|
Destination: &language,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
app.Action = func(c *cli.Context) {
|
||||||
|
name := "someone"
|
||||||
|
if len(c.Args()) > 0 {
|
||||||
|
name = c.Args()[0]
|
||||||
|
}
|
||||||
|
if language == "spanish" {
|
||||||
|
println("Hola", name)
|
||||||
|
} else {
|
||||||
|
println("Hello", name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
See full list of flags at http://godoc.org/github.com/codegangsta/cli
|
See full list of flags at http://godoc.org/github.com/codegangsta/cli
|
||||||
|
|
||||||
#### Alternate Names
|
#### Alternate Names
|
||||||
|
|
@ -207,6 +241,7 @@ app.Flags = []cli.Flag {
|
||||||
### Subcommands
|
### Subcommands
|
||||||
|
|
||||||
Subcommands can be defined for a more git-like command line app.
|
Subcommands can be defined for a more git-like command line app.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
...
|
...
|
||||||
app.Commands = []cli.Command{
|
app.Commands = []cli.Command{
|
||||||
|
|
@ -257,6 +292,7 @@ You can enable completion commands by setting the `EnableBashCompletion`
|
||||||
flag on the `App` object. By default, this setting will only auto-complete to
|
flag on the `App` object. By default, this setting will only auto-complete to
|
||||||
show an app's subcommands, but you can write your own completion methods for
|
show an app's subcommands, but you can write your own completion methods for
|
||||||
the App or its subcommands.
|
the App or its subcommands.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
...
|
...
|
||||||
var tasks = []string{"cook", "clean", "laundry", "eat", "sleep", "code"}
|
var tasks = []string{"cook", "clean", "laundry", "eat", "sleep", "code"}
|
||||||
|
|
@ -299,8 +335,8 @@ automatically install it there if you are distributing a package). Don't forget
|
||||||
to source the file to make it active in the current shell.
|
to source the file to make it active in the current shell.
|
||||||
|
|
||||||
```
|
```
|
||||||
sudo cp src/bash_autocomplete /etc/bash_completion.d/<myprogram>
|
sudo cp src/bash_autocomplete /etc/bash_completion.d/<myprogram>
|
||||||
source /etc/bash_completion.d/<myprogram>
|
source /etc/bash_completion.d/<myprogram>
|
||||||
```
|
```
|
||||||
|
|
||||||
Alternatively, you can just document that users should source the generic
|
Alternatively, you can just document that users should source the generic
|
||||||
|
|
@ -308,8 +344,9 @@ Alternatively, you can just document that users should source the generic
|
||||||
to the name of their program (as above).
|
to the name of their program (as above).
|
||||||
|
|
||||||
## Contribution Guidelines
|
## Contribution Guidelines
|
||||||
|
|
||||||
Feel free to put up a pull request to fix a bug or maybe add a feature. I will give it a code review and make sure that it does not break backwards compatibility. If I or any other collaborators agree that it is in line with the vision of the project, we will work with you to get the code into a mergeable state and merge it into the master branch.
|
Feel free to put up a pull request to fix a bug or maybe add a feature. I will give it a code review and make sure that it does not break backwards compatibility. If I or any other collaborators agree that it is in line with the vision of the project, we will work with you to get the code into a mergeable state and merge it into the master branch.
|
||||||
|
|
||||||
If you have contributed something significant to the project, I will most likely add you as a collaborator. As a collaborator you are given the ability to merge others pull requests. It is very important that new code does not break existing code, so be careful about what code you do choose to merge. If you have any questions feel free to link @codegangsta to the issue in question and we can review it together.
|
If you have contributed something significant to the project, I will most likely add you as a collaborator. As a collaborator you are given the ability to merge others pull requests. It is very important that new code does not break existing code, so be careful about what code you do choose to merge. If you have any questions feel free to link @codegangsta to the issue in question and we can review it togexper.
|
||||||
|
|
||||||
If you feel like you have contributed to the project but have not yet been added as a collaborator, I probably forgot to add you. Hit @codegangsta up over email and we will get it figured out.
|
If you feel like you have contributed to the project but have not yet been added as a collaborator, I probably forgot to add you. Hit @codegangsta up over email and we will get it figured out.
|
||||||
|
|
|
||||||
62
Godeps/_workspace/src/github.com/codegangsta/cli/app.go
generated
vendored
|
|
@ -5,18 +5,21 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// App is the main structure of a cli application. It is recomended that
|
// App is the main structure of a cli application. It is recommended that
|
||||||
// an app be created with the cli.NewApp() function
|
// an app be created with the cli.NewApp() function
|
||||||
type App struct {
|
type App struct {
|
||||||
// The name of the program. Defaults to os.Args[0]
|
// The name of the program. Defaults to path.Base(os.Args[0])
|
||||||
Name string
|
Name string
|
||||||
// Full name of command for help, defaults to Name
|
// Full name of command for help, defaults to Name
|
||||||
HelpName string
|
HelpName string
|
||||||
// Description of the program.
|
// Description of the program.
|
||||||
Usage string
|
Usage string
|
||||||
|
// Text to override the USAGE section of help
|
||||||
|
UsageText string
|
||||||
// Description of the program argument format.
|
// Description of the program argument format.
|
||||||
ArgsUsage string
|
ArgsUsage string
|
||||||
// Version of the program
|
// Version of the program
|
||||||
|
|
@ -43,6 +46,10 @@ type App struct {
|
||||||
Action func(context *Context)
|
Action func(context *Context)
|
||||||
// Execute this function if the proper command cannot be found
|
// Execute this function if the proper command cannot be found
|
||||||
CommandNotFound func(context *Context, command string)
|
CommandNotFound func(context *Context, command string)
|
||||||
|
// Execute this function, if an usage error occurs. This is useful for displaying customized usage error messages.
|
||||||
|
// This function is able to replace the original error messages.
|
||||||
|
// If this function is not set, the "Incorrect usage" is displayed and the execution is interrupted.
|
||||||
|
OnUsageError func(context *Context, err error, isSubcommand bool) error
|
||||||
// Compilation date
|
// Compilation date
|
||||||
Compiled time.Time
|
Compiled time.Time
|
||||||
// List of all authors who contributed
|
// List of all authors who contributed
|
||||||
|
|
@ -70,9 +77,10 @@ func compileTime() time.Time {
|
||||||
// Creates a new cli Application with some reasonable defaults for Name, Usage, Version and Action.
|
// Creates a new cli Application with some reasonable defaults for Name, Usage, Version and Action.
|
||||||
func NewApp() *App {
|
func NewApp() *App {
|
||||||
return &App{
|
return &App{
|
||||||
Name: os.Args[0],
|
Name: path.Base(os.Args[0]),
|
||||||
HelpName: os.Args[0],
|
HelpName: path.Base(os.Args[0]),
|
||||||
Usage: "A new cli application",
|
Usage: "A new cli application",
|
||||||
|
UsageText: "",
|
||||||
Version: "0.0.0",
|
Version: "0.0.0",
|
||||||
BashComplete: DefaultAppComplete,
|
BashComplete: DefaultAppComplete,
|
||||||
Action: helpCommand.Action,
|
Action: helpCommand.Action,
|
||||||
|
|
@ -118,25 +126,28 @@ func (a *App) Run(arguments []string) (err error) {
|
||||||
set.SetOutput(ioutil.Discard)
|
set.SetOutput(ioutil.Discard)
|
||||||
err = set.Parse(arguments[1:])
|
err = set.Parse(arguments[1:])
|
||||||
nerr := normalizeFlags(a.Flags, set)
|
nerr := normalizeFlags(a.Flags, set)
|
||||||
|
context := NewContext(a, set, nil)
|
||||||
if nerr != nil {
|
if nerr != nil {
|
||||||
fmt.Fprintln(a.Writer, nerr)
|
fmt.Fprintln(a.Writer, nerr)
|
||||||
context := NewContext(a, set, nil)
|
|
||||||
ShowAppHelp(context)
|
ShowAppHelp(context)
|
||||||
return nerr
|
return nerr
|
||||||
}
|
}
|
||||||
context := NewContext(a, set, nil)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintln(a.Writer, "Incorrect Usage.")
|
|
||||||
fmt.Fprintln(a.Writer)
|
|
||||||
ShowAppHelp(context)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if checkCompletions(context) {
|
if checkCompletions(context) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
if a.OnUsageError != nil {
|
||||||
|
err := a.OnUsageError(context, err, false)
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(a.Writer, "%s\n\n", "Incorrect Usage.")
|
||||||
|
ShowAppHelp(context)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if !a.HideHelp && checkHelp(context) {
|
if !a.HideHelp && checkHelp(context) {
|
||||||
ShowAppHelp(context)
|
ShowAppHelp(context)
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -149,8 +160,7 @@ func (a *App) Run(arguments []string) (err error) {
|
||||||
|
|
||||||
if a.After != nil {
|
if a.After != nil {
|
||||||
defer func() {
|
defer func() {
|
||||||
afterErr := a.After(context)
|
if afterErr := a.After(context); afterErr != nil {
|
||||||
if afterErr != nil {
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = NewMultiError(err, afterErr)
|
err = NewMultiError(err, afterErr)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -161,8 +171,10 @@ func (a *App) Run(arguments []string) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if a.Before != nil {
|
if a.Before != nil {
|
||||||
err := a.Before(context)
|
err = a.Before(context)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
fmt.Fprintf(a.Writer, "%v\n\n", err)
|
||||||
|
ShowAppHelp(context)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -233,17 +245,21 @@ func (a *App) RunAsSubcommand(ctx *Context) (err error) {
|
||||||
return nerr
|
return nerr
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintln(a.Writer, "Incorrect Usage.")
|
|
||||||
fmt.Fprintln(a.Writer)
|
|
||||||
ShowSubcommandHelp(context)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if checkCompletions(context) {
|
if checkCompletions(context) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
if a.OnUsageError != nil {
|
||||||
|
err = a.OnUsageError(context, err, true)
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(a.Writer, "%s\n\n", "Incorrect Usage.")
|
||||||
|
ShowSubcommandHelp(context)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if len(a.Commands) > 0 {
|
if len(a.Commands) > 0 {
|
||||||
if checkSubcommandHelp(context) {
|
if checkSubcommandHelp(context) {
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
16
Godeps/_workspace/src/github.com/codegangsta/cli/appveyor.yml
generated
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
version: "{build}"
|
||||||
|
|
||||||
|
os: Windows Server 2012 R2
|
||||||
|
|
||||||
|
install:
|
||||||
|
- go version
|
||||||
|
- go env
|
||||||
|
|
||||||
|
build_script:
|
||||||
|
- cd %APPVEYOR_BUILD_FOLDER%
|
||||||
|
- go vet ./...
|
||||||
|
- go test -v ./...
|
||||||
|
|
||||||
|
test: off
|
||||||
|
|
||||||
|
deploy: off
|
||||||
5
Godeps/_workspace/src/github.com/codegangsta/cli/autocomplete/bash_autocomplete
generated
vendored
|
|
@ -3,13 +3,12 @@
|
||||||
: ${PROG:=$(basename ${BASH_SOURCE})}
|
: ${PROG:=$(basename ${BASH_SOURCE})}
|
||||||
|
|
||||||
_cli_bash_autocomplete() {
|
_cli_bash_autocomplete() {
|
||||||
local cur prev opts base
|
local cur opts base
|
||||||
COMPREPLY=()
|
COMPREPLY=()
|
||||||
cur="${COMP_WORDS[COMP_CWORD]}"
|
cur="${COMP_WORDS[COMP_CWORD]}"
|
||||||
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
|
||||||
opts=$( ${COMP_WORDS[@]:0:$COMP_CWORD} --generate-bash-completion )
|
opts=$( ${COMP_WORDS[@]:0:$COMP_CWORD} --generate-bash-completion )
|
||||||
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
|
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
complete -F _cli_bash_autocomplete $PROG
|
complete -F _cli_bash_autocomplete $PROG
|
||||||
|
|
|
||||||
108
Godeps/_workspace/src/github.com/codegangsta/cli/command.go
generated
vendored
|
|
@ -16,6 +16,8 @@ type Command struct {
|
||||||
Aliases []string
|
Aliases []string
|
||||||
// A short description of the usage of this command
|
// A short description of the usage of this command
|
||||||
Usage string
|
Usage string
|
||||||
|
// Custom text to show on USAGE section of help
|
||||||
|
UsageText string
|
||||||
// A longer explanation of how the command works
|
// A longer explanation of how the command works
|
||||||
Description string
|
Description string
|
||||||
// A short description of the arguments of this command
|
// A short description of the arguments of this command
|
||||||
|
|
@ -30,6 +32,10 @@ type Command struct {
|
||||||
After func(context *Context) error
|
After func(context *Context) error
|
||||||
// The function to call when this command is invoked
|
// The function to call when this command is invoked
|
||||||
Action func(context *Context)
|
Action func(context *Context)
|
||||||
|
// Execute this function, if an usage error occurs. This is useful for displaying customized usage error messages.
|
||||||
|
// This function is able to replace the original error messages.
|
||||||
|
// If this function is not set, the "Incorrect usage" is displayed and the execution is interrupted.
|
||||||
|
OnUsageError func(context *Context, err error) error
|
||||||
// List of child commands
|
// List of child commands
|
||||||
Subcommands []Command
|
Subcommands []Command
|
||||||
// List of flags to parse
|
// List of flags to parse
|
||||||
|
|
@ -54,8 +60,8 @@ func (c Command) FullName() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invokes the command given the context, parses ctx.Args() to generate command-specific flags
|
// Invokes the command given the context, parses ctx.Args() to generate command-specific flags
|
||||||
func (c Command) Run(ctx *Context) error {
|
func (c Command) Run(ctx *Context) (err error) {
|
||||||
if len(c.Subcommands) > 0 || c.Before != nil || c.After != nil {
|
if len(c.Subcommands) > 0 {
|
||||||
return c.startApp(ctx)
|
return c.startApp(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -74,41 +80,54 @@ func (c Command) Run(ctx *Context) error {
|
||||||
set := flagSet(c.Name, c.Flags)
|
set := flagSet(c.Name, c.Flags)
|
||||||
set.SetOutput(ioutil.Discard)
|
set.SetOutput(ioutil.Discard)
|
||||||
|
|
||||||
firstFlagIndex := -1
|
if !c.SkipFlagParsing {
|
||||||
terminatorIndex := -1
|
firstFlagIndex := -1
|
||||||
for index, arg := range ctx.Args() {
|
terminatorIndex := -1
|
||||||
if arg == "--" {
|
for index, arg := range ctx.Args() {
|
||||||
terminatorIndex = index
|
if arg == "--" {
|
||||||
break
|
terminatorIndex = index
|
||||||
} else if strings.HasPrefix(arg, "-") && firstFlagIndex == -1 {
|
break
|
||||||
firstFlagIndex = index
|
} else if arg == "-" {
|
||||||
|
// Do nothing. A dash alone is not really a flag.
|
||||||
|
continue
|
||||||
|
} else if strings.HasPrefix(arg, "-") && firstFlagIndex == -1 {
|
||||||
|
firstFlagIndex = index
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
var err error
|
if firstFlagIndex > -1 {
|
||||||
if firstFlagIndex > -1 && !c.SkipFlagParsing {
|
args := ctx.Args()
|
||||||
args := ctx.Args()
|
regularArgs := make([]string, len(args[1:firstFlagIndex]))
|
||||||
regularArgs := make([]string, len(args[1:firstFlagIndex]))
|
copy(regularArgs, args[1:firstFlagIndex])
|
||||||
copy(regularArgs, args[1:firstFlagIndex])
|
|
||||||
|
|
||||||
var flagArgs []string
|
var flagArgs []string
|
||||||
if terminatorIndex > -1 {
|
if terminatorIndex > -1 {
|
||||||
flagArgs = args[firstFlagIndex:terminatorIndex]
|
flagArgs = args[firstFlagIndex:terminatorIndex]
|
||||||
regularArgs = append(regularArgs, args[terminatorIndex:]...)
|
regularArgs = append(regularArgs, args[terminatorIndex:]...)
|
||||||
|
} else {
|
||||||
|
flagArgs = args[firstFlagIndex:]
|
||||||
|
}
|
||||||
|
|
||||||
|
err = set.Parse(append(flagArgs, regularArgs...))
|
||||||
} else {
|
} else {
|
||||||
flagArgs = args[firstFlagIndex:]
|
err = set.Parse(ctx.Args().Tail())
|
||||||
}
|
}
|
||||||
|
|
||||||
err = set.Parse(append(flagArgs, regularArgs...))
|
|
||||||
} else {
|
} else {
|
||||||
err = set.Parse(ctx.Args().Tail())
|
if c.SkipFlagParsing {
|
||||||
|
err = set.Parse(append([]string{"--"}, ctx.Args().Tail()...))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintln(ctx.App.Writer, "Incorrect Usage.")
|
if c.OnUsageError != nil {
|
||||||
fmt.Fprintln(ctx.App.Writer)
|
err := c.OnUsageError(ctx, err)
|
||||||
ShowCommandHelp(ctx, c.Name)
|
return err
|
||||||
return err
|
} else {
|
||||||
|
fmt.Fprintln(ctx.App.Writer, "Incorrect Usage.")
|
||||||
|
fmt.Fprintln(ctx.App.Writer)
|
||||||
|
ShowCommandHelp(ctx, c.Name)
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nerr := normalizeFlags(c.Flags, set)
|
nerr := normalizeFlags(c.Flags, set)
|
||||||
|
|
@ -127,6 +146,30 @@ func (c Command) Run(ctx *Context) error {
|
||||||
if checkCommandHelp(context, c.Name) {
|
if checkCommandHelp(context, c.Name) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if c.After != nil {
|
||||||
|
defer func() {
|
||||||
|
afterErr := c.After(context)
|
||||||
|
if afterErr != nil {
|
||||||
|
if err != nil {
|
||||||
|
err = NewMultiError(err, afterErr)
|
||||||
|
} else {
|
||||||
|
err = afterErr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.Before != nil {
|
||||||
|
err := c.Before(context)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintln(ctx.App.Writer, err)
|
||||||
|
fmt.Fprintln(ctx.App.Writer)
|
||||||
|
ShowCommandHelp(ctx, c.Name)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
context.Command = c
|
context.Command = c
|
||||||
c.Action(context)
|
c.Action(context)
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -160,7 +203,7 @@ func (c Command) startApp(ctx *Context) error {
|
||||||
if c.HelpName == "" {
|
if c.HelpName == "" {
|
||||||
app.HelpName = c.HelpName
|
app.HelpName = c.HelpName
|
||||||
} else {
|
} else {
|
||||||
app.HelpName = fmt.Sprintf("%s %s", ctx.App.Name, c.Name)
|
app.HelpName = app.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.Description != "" {
|
if c.Description != "" {
|
||||||
|
|
@ -199,12 +242,9 @@ func (c Command) startApp(ctx *Context) error {
|
||||||
app.Action = helpSubcommand.Action
|
app.Action = helpSubcommand.Action
|
||||||
}
|
}
|
||||||
|
|
||||||
var newCmds []Command
|
for index, cc := range app.Commands {
|
||||||
for _, cc := range app.Commands {
|
app.Commands[index].commandNamePath = []string{c.Name, cc.Name}
|
||||||
cc.commandNamePath = []string{c.Name, cc.Name}
|
|
||||||
newCmds = append(newCmds, cc)
|
|
||||||
}
|
}
|
||||||
app.Commands = newCmds
|
|
||||||
|
|
||||||
return app.RunAsSubcommand(ctx)
|
return app.RunAsSubcommand(ctx)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
6
Godeps/_workspace/src/github.com/codegangsta/cli/context.go
generated
vendored
|
|
@ -163,7 +163,7 @@ func (c *Context) GlobalIsSet(name string) bool {
|
||||||
// Returns a slice of flag names used in this context.
|
// Returns a slice of flag names used in this context.
|
||||||
func (c *Context) FlagNames() (names []string) {
|
func (c *Context) FlagNames() (names []string) {
|
||||||
for _, flag := range c.Command.Flags {
|
for _, flag := range c.Command.Flags {
|
||||||
name := strings.Split(flag.getName(), ",")[0]
|
name := strings.Split(flag.GetName(), ",")[0]
|
||||||
if name == "help" {
|
if name == "help" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
@ -175,7 +175,7 @@ func (c *Context) FlagNames() (names []string) {
|
||||||
// Returns a slice of global flag names used by the app.
|
// Returns a slice of global flag names used by the app.
|
||||||
func (c *Context) GlobalFlagNames() (names []string) {
|
func (c *Context) GlobalFlagNames() (names []string) {
|
||||||
for _, flag := range c.App.Flags {
|
for _, flag := range c.App.Flags {
|
||||||
name := strings.Split(flag.getName(), ",")[0]
|
name := strings.Split(flag.GetName(), ",")[0]
|
||||||
if name == "help" || name == "version" {
|
if name == "help" || name == "version" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
@ -360,7 +360,7 @@ func normalizeFlags(flags []Flag, set *flag.FlagSet) error {
|
||||||
visited[f.Name] = true
|
visited[f.Name] = true
|
||||||
})
|
})
|
||||||
for _, f := range flags {
|
for _, f := range flags {
|
||||||
parts := strings.Split(f.getName(), ",")
|
parts := strings.Split(f.GetName(), ",")
|
||||||
if len(parts) == 1 {
|
if len(parts) == 1 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
||||||
135
Godeps/_workspace/src/github.com/codegangsta/cli/flag.go
generated
vendored
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
@ -29,13 +30,13 @@ var HelpFlag = BoolFlag{
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flag is a common interface related to parsing flags in cli.
|
// Flag is a common interface related to parsing flags in cli.
|
||||||
// For more advanced flag parsing techniques, it is recomended that
|
// For more advanced flag parsing techniques, it is recommended that
|
||||||
// this interface be implemented.
|
// this interface be implemented.
|
||||||
type Flag interface {
|
type Flag interface {
|
||||||
fmt.Stringer
|
fmt.Stringer
|
||||||
// Apply Flag settings to the given flag set
|
// Apply Flag settings to the given flag set
|
||||||
Apply(*flag.FlagSet)
|
Apply(*flag.FlagSet)
|
||||||
getName() string
|
GetName() string
|
||||||
}
|
}
|
||||||
|
|
||||||
func flagSet(name string, flags []Flag) *flag.FlagSet {
|
func flagSet(name string, flags []Flag) *flag.FlagSet {
|
||||||
|
|
@ -73,7 +74,18 @@ type GenericFlag struct {
|
||||||
// help text to the user (uses the String() method of the generic flag to show
|
// help text to the user (uses the String() method of the generic flag to show
|
||||||
// the value)
|
// the value)
|
||||||
func (f GenericFlag) String() string {
|
func (f GenericFlag) String() string {
|
||||||
return withEnvHint(f.EnvVar, fmt.Sprintf("%s%s \"%v\"\t%v", prefixFor(f.Name), f.Name, f.Value, f.Usage))
|
return withEnvHint(f.EnvVar, fmt.Sprintf("%s %v\t%v", prefixedNames(f.Name), f.FormatValueHelp(), f.Usage))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f GenericFlag) FormatValueHelp() string {
|
||||||
|
if f.Value == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
s := f.Value.String()
|
||||||
|
if len(s) == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("\"%s\"", s)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply takes the flagset and calls Set on the generic flag with the value
|
// Apply takes the flagset and calls Set on the generic flag with the value
|
||||||
|
|
@ -95,7 +107,7 @@ func (f GenericFlag) Apply(set *flag.FlagSet) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f GenericFlag) getName() string {
|
func (f GenericFlag) GetName() string {
|
||||||
return f.Name
|
return f.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -159,7 +171,7 @@ func (f StringSliceFlag) Apply(set *flag.FlagSet) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f StringSliceFlag) getName() string {
|
func (f StringSliceFlag) GetName() string {
|
||||||
return f.Name
|
return f.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -231,15 +243,16 @@ func (f IntSliceFlag) Apply(set *flag.FlagSet) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f IntSliceFlag) getName() string {
|
func (f IntSliceFlag) GetName() string {
|
||||||
return f.Name
|
return f.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
// BoolFlag is a switch that defaults to false
|
// BoolFlag is a switch that defaults to false
|
||||||
type BoolFlag struct {
|
type BoolFlag struct {
|
||||||
Name string
|
Name string
|
||||||
Usage string
|
Usage string
|
||||||
EnvVar string
|
EnvVar string
|
||||||
|
Destination *bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns a readable representation of this value (for usage defaults)
|
// String returns a readable representation of this value (for usage defaults)
|
||||||
|
|
@ -264,20 +277,25 @@ func (f BoolFlag) Apply(set *flag.FlagSet) {
|
||||||
}
|
}
|
||||||
|
|
||||||
eachName(f.Name, func(name string) {
|
eachName(f.Name, func(name string) {
|
||||||
|
if f.Destination != nil {
|
||||||
|
set.BoolVar(f.Destination, name, val, f.Usage)
|
||||||
|
return
|
||||||
|
}
|
||||||
set.Bool(name, val, f.Usage)
|
set.Bool(name, val, f.Usage)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f BoolFlag) getName() string {
|
func (f BoolFlag) GetName() string {
|
||||||
return f.Name
|
return f.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
// BoolTFlag this represents a boolean flag that is true by default, but can
|
// BoolTFlag this represents a boolean flag that is true by default, but can
|
||||||
// still be set to false by --some-flag=false
|
// still be set to false by --some-flag=false
|
||||||
type BoolTFlag struct {
|
type BoolTFlag struct {
|
||||||
Name string
|
Name string
|
||||||
Usage string
|
Usage string
|
||||||
EnvVar string
|
EnvVar string
|
||||||
|
Destination *bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns a readable representation of this value (for usage defaults)
|
// String returns a readable representation of this value (for usage defaults)
|
||||||
|
|
@ -302,34 +320,38 @@ func (f BoolTFlag) Apply(set *flag.FlagSet) {
|
||||||
}
|
}
|
||||||
|
|
||||||
eachName(f.Name, func(name string) {
|
eachName(f.Name, func(name string) {
|
||||||
|
if f.Destination != nil {
|
||||||
|
set.BoolVar(f.Destination, name, val, f.Usage)
|
||||||
|
return
|
||||||
|
}
|
||||||
set.Bool(name, val, f.Usage)
|
set.Bool(name, val, f.Usage)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f BoolTFlag) getName() string {
|
func (f BoolTFlag) GetName() string {
|
||||||
return f.Name
|
return f.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
// StringFlag represents a flag that takes as string value
|
// StringFlag represents a flag that takes as string value
|
||||||
type StringFlag struct {
|
type StringFlag struct {
|
||||||
Name string
|
Name string
|
||||||
Value string
|
Value string
|
||||||
Usage string
|
Usage string
|
||||||
EnvVar string
|
EnvVar string
|
||||||
|
Destination *string
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns the usage
|
// String returns the usage
|
||||||
func (f StringFlag) String() string {
|
func (f StringFlag) String() string {
|
||||||
var fmtString string
|
return withEnvHint(f.EnvVar, fmt.Sprintf("%s %v\t%v", prefixedNames(f.Name), f.FormatValueHelp(), f.Usage))
|
||||||
fmtString = "%s %v\t%v"
|
}
|
||||||
|
|
||||||
if len(f.Value) > 0 {
|
func (f StringFlag) FormatValueHelp() string {
|
||||||
fmtString = "%s \"%v\"\t%v"
|
s := f.Value
|
||||||
} else {
|
if len(s) == 0 {
|
||||||
fmtString = "%s %v\t%v"
|
return ""
|
||||||
}
|
}
|
||||||
|
return fmt.Sprintf("\"%s\"", s)
|
||||||
return withEnvHint(f.EnvVar, fmt.Sprintf(fmtString, prefixedNames(f.Name), f.Value, f.Usage))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply populates the flag given the flag set and environment
|
// Apply populates the flag given the flag set and environment
|
||||||
|
|
@ -345,21 +367,26 @@ func (f StringFlag) Apply(set *flag.FlagSet) {
|
||||||
}
|
}
|
||||||
|
|
||||||
eachName(f.Name, func(name string) {
|
eachName(f.Name, func(name string) {
|
||||||
|
if f.Destination != nil {
|
||||||
|
set.StringVar(f.Destination, name, f.Value, f.Usage)
|
||||||
|
return
|
||||||
|
}
|
||||||
set.String(name, f.Value, f.Usage)
|
set.String(name, f.Value, f.Usage)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f StringFlag) getName() string {
|
func (f StringFlag) GetName() string {
|
||||||
return f.Name
|
return f.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
// IntFlag is a flag that takes an integer
|
// IntFlag is a flag that takes an integer
|
||||||
// Errors if the value provided cannot be parsed
|
// Errors if the value provided cannot be parsed
|
||||||
type IntFlag struct {
|
type IntFlag struct {
|
||||||
Name string
|
Name string
|
||||||
Value int
|
Value int
|
||||||
Usage string
|
Usage string
|
||||||
EnvVar string
|
EnvVar string
|
||||||
|
Destination *int
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns the usage
|
// String returns the usage
|
||||||
|
|
@ -383,21 +410,26 @@ func (f IntFlag) Apply(set *flag.FlagSet) {
|
||||||
}
|
}
|
||||||
|
|
||||||
eachName(f.Name, func(name string) {
|
eachName(f.Name, func(name string) {
|
||||||
|
if f.Destination != nil {
|
||||||
|
set.IntVar(f.Destination, name, f.Value, f.Usage)
|
||||||
|
return
|
||||||
|
}
|
||||||
set.Int(name, f.Value, f.Usage)
|
set.Int(name, f.Value, f.Usage)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f IntFlag) getName() string {
|
func (f IntFlag) GetName() string {
|
||||||
return f.Name
|
return f.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
// DurationFlag is a flag that takes a duration specified in Go's duration
|
// DurationFlag is a flag that takes a duration specified in Go's duration
|
||||||
// format: https://golang.org/pkg/time/#ParseDuration
|
// format: https://golang.org/pkg/time/#ParseDuration
|
||||||
type DurationFlag struct {
|
type DurationFlag struct {
|
||||||
Name string
|
Name string
|
||||||
Value time.Duration
|
Value time.Duration
|
||||||
Usage string
|
Usage string
|
||||||
EnvVar string
|
EnvVar string
|
||||||
|
Destination *time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns a readable representation of this value (for usage defaults)
|
// String returns a readable representation of this value (for usage defaults)
|
||||||
|
|
@ -421,21 +453,26 @@ func (f DurationFlag) Apply(set *flag.FlagSet) {
|
||||||
}
|
}
|
||||||
|
|
||||||
eachName(f.Name, func(name string) {
|
eachName(f.Name, func(name string) {
|
||||||
|
if f.Destination != nil {
|
||||||
|
set.DurationVar(f.Destination, name, f.Value, f.Usage)
|
||||||
|
return
|
||||||
|
}
|
||||||
set.Duration(name, f.Value, f.Usage)
|
set.Duration(name, f.Value, f.Usage)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f DurationFlag) getName() string {
|
func (f DurationFlag) GetName() string {
|
||||||
return f.Name
|
return f.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
// Float64Flag is a flag that takes an float value
|
// Float64Flag is a flag that takes an float value
|
||||||
// Errors if the value provided cannot be parsed
|
// Errors if the value provided cannot be parsed
|
||||||
type Float64Flag struct {
|
type Float64Flag struct {
|
||||||
Name string
|
Name string
|
||||||
Value float64
|
Value float64
|
||||||
Usage string
|
Usage string
|
||||||
EnvVar string
|
EnvVar string
|
||||||
|
Destination *float64
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns the usage
|
// String returns the usage
|
||||||
|
|
@ -458,11 +495,15 @@ func (f Float64Flag) Apply(set *flag.FlagSet) {
|
||||||
}
|
}
|
||||||
|
|
||||||
eachName(f.Name, func(name string) {
|
eachName(f.Name, func(name string) {
|
||||||
|
if f.Destination != nil {
|
||||||
|
set.Float64Var(f.Destination, name, f.Value, f.Usage)
|
||||||
|
return
|
||||||
|
}
|
||||||
set.Float64(name, f.Value, f.Usage)
|
set.Float64(name, f.Value, f.Usage)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f Float64Flag) getName() string {
|
func (f Float64Flag) GetName() string {
|
||||||
return f.Name
|
return f.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -491,7 +532,15 @@ func prefixedNames(fullName string) (prefixed string) {
|
||||||
func withEnvHint(envVar, str string) string {
|
func withEnvHint(envVar, str string) string {
|
||||||
envText := ""
|
envText := ""
|
||||||
if envVar != "" {
|
if envVar != "" {
|
||||||
envText = fmt.Sprintf(" [$%s]", strings.Join(strings.Split(envVar, ","), ", $"))
|
prefix := "$"
|
||||||
|
suffix := ""
|
||||||
|
sep := ", $"
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
prefix = "%"
|
||||||
|
suffix = "%"
|
||||||
|
sep = "%, %"
|
||||||
|
}
|
||||||
|
envText = fmt.Sprintf(" [%s%s%s]", prefix, strings.Join(strings.Split(envVar, ","), sep), suffix)
|
||||||
}
|
}
|
||||||
return str + envText
|
return str + envText
|
||||||
}
|
}
|
||||||
|
|
|
||||||
6
Godeps/_workspace/src/github.com/codegangsta/cli/help.go
generated
vendored
|
|
@ -15,7 +15,7 @@ var AppHelpTemplate = `NAME:
|
||||||
{{.Name}} - {{.Usage}}
|
{{.Name}} - {{.Usage}}
|
||||||
|
|
||||||
USAGE:
|
USAGE:
|
||||||
{{.HelpName}} {{if .Flags}}[global options]{{end}}{{if .Commands}} command [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}
|
{{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}} {{if .Flags}}[global options]{{end}}{{if .Commands}} command [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}
|
||||||
{{if .Version}}
|
{{if .Version}}
|
||||||
VERSION:
|
VERSION:
|
||||||
{{.Version}}
|
{{.Version}}
|
||||||
|
|
@ -180,7 +180,9 @@ func printHelp(out io.Writer, templ string, data interface{}) {
|
||||||
t := template.Must(template.New("help").Funcs(funcMap).Parse(templ))
|
t := template.Must(template.New("help").Funcs(funcMap).Parse(templ))
|
||||||
err := t.Execute(w, data)
|
err := t.Execute(w, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
// If the writer is closed, t.Execute will fail, and there's nothing
|
||||||
|
// we can do to recover. We could send this to os.Stderr if we need.
|
||||||
|
return
|
||||||
}
|
}
|
||||||
w.Flush()
|
w.Flush()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
13
Godeps/_workspace/src/github.com/davecgh/go-spew/LICENSE
generated
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
Copyright (c) 2012-2013 Dave Collins <dave@davec.name>
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
151
Godeps/_workspace/src/github.com/davecgh/go-spew/spew/bypass.go
generated
vendored
Normal file
|
|
@ -0,0 +1,151 @@
|
||||||
|
// Copyright (c) 2015 Dave Collins <dave@davec.name>
|
||||||
|
//
|
||||||
|
// Permission to use, copy, modify, and distribute this software for any
|
||||||
|
// purpose with or without fee is hereby granted, provided that the above
|
||||||
|
// copyright notice and this permission notice appear in all copies.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
// NOTE: Due to the following build constraints, this file will only be compiled
|
||||||
|
// when the code is not running on Google App Engine and "-tags disableunsafe"
|
||||||
|
// is not added to the go build command line.
|
||||||
|
// +build !appengine,!disableunsafe
|
||||||
|
|
||||||
|
package spew
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// UnsafeDisabled is a build-time constant which specifies whether or
|
||||||
|
// not access to the unsafe package is available.
|
||||||
|
UnsafeDisabled = false
|
||||||
|
|
||||||
|
// ptrSize is the size of a pointer on the current arch.
|
||||||
|
ptrSize = unsafe.Sizeof((*byte)(nil))
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// offsetPtr, offsetScalar, and offsetFlag are the offsets for the
|
||||||
|
// internal reflect.Value fields. These values are valid before golang
|
||||||
|
// commit ecccf07e7f9d which changed the format. The are also valid
|
||||||
|
// after commit 82f48826c6c7 which changed the format again to mirror
|
||||||
|
// the original format. Code in the init function updates these offsets
|
||||||
|
// as necessary.
|
||||||
|
offsetPtr = uintptr(ptrSize)
|
||||||
|
offsetScalar = uintptr(0)
|
||||||
|
offsetFlag = uintptr(ptrSize * 2)
|
||||||
|
|
||||||
|
// flagKindWidth and flagKindShift indicate various bits that the
|
||||||
|
// reflect package uses internally to track kind information.
|
||||||
|
//
|
||||||
|
// flagRO indicates whether or not the value field of a reflect.Value is
|
||||||
|
// read-only.
|
||||||
|
//
|
||||||
|
// flagIndir indicates whether the value field of a reflect.Value is
|
||||||
|
// the actual data or a pointer to the data.
|
||||||
|
//
|
||||||
|
// These values are valid before golang commit 90a7c3c86944 which
|
||||||
|
// changed their positions. Code in the init function updates these
|
||||||
|
// flags as necessary.
|
||||||
|
flagKindWidth = uintptr(5)
|
||||||
|
flagKindShift = uintptr(flagKindWidth - 1)
|
||||||
|
flagRO = uintptr(1 << 0)
|
||||||
|
flagIndir = uintptr(1 << 1)
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
// Older versions of reflect.Value stored small integers directly in the
|
||||||
|
// ptr field (which is named val in the older versions). Versions
|
||||||
|
// between commits ecccf07e7f9d and 82f48826c6c7 added a new field named
|
||||||
|
// scalar for this purpose which unfortunately came before the flag
|
||||||
|
// field, so the offset of the flag field is different for those
|
||||||
|
// versions.
|
||||||
|
//
|
||||||
|
// This code constructs a new reflect.Value from a known small integer
|
||||||
|
// and checks if the size of the reflect.Value struct indicates it has
|
||||||
|
// the scalar field. When it does, the offsets are updated accordingly.
|
||||||
|
vv := reflect.ValueOf(0xf00)
|
||||||
|
if unsafe.Sizeof(vv) == (ptrSize * 4) {
|
||||||
|
offsetScalar = ptrSize * 2
|
||||||
|
offsetFlag = ptrSize * 3
|
||||||
|
}
|
||||||
|
|
||||||
|
// Commit 90a7c3c86944 changed the flag positions such that the low
|
||||||
|
// order bits are the kind. This code extracts the kind from the flags
|
||||||
|
// field and ensures it's the correct type. When it's not, the flag
|
||||||
|
// order has been changed to the newer format, so the flags are updated
|
||||||
|
// accordingly.
|
||||||
|
upf := unsafe.Pointer(uintptr(unsafe.Pointer(&vv)) + offsetFlag)
|
||||||
|
upfv := *(*uintptr)(upf)
|
||||||
|
flagKindMask := uintptr((1<<flagKindWidth - 1) << flagKindShift)
|
||||||
|
if (upfv&flagKindMask)>>flagKindShift != uintptr(reflect.Int) {
|
||||||
|
flagKindShift = 0
|
||||||
|
flagRO = 1 << 5
|
||||||
|
flagIndir = 1 << 6
|
||||||
|
|
||||||
|
// Commit adf9b30e5594 modified the flags to separate the
|
||||||
|
// flagRO flag into two bits which specifies whether or not the
|
||||||
|
// field is embedded. This causes flagIndir to move over a bit
|
||||||
|
// and means that flagRO is the combination of either of the
|
||||||
|
// original flagRO bit and the new bit.
|
||||||
|
//
|
||||||
|
// This code detects the change by extracting what used to be
|
||||||
|
// the indirect bit to ensure it's set. When it's not, the flag
|
||||||
|
// order has been changed to the newer format, so the flags are
|
||||||
|
// updated accordingly.
|
||||||
|
if upfv&flagIndir == 0 {
|
||||||
|
flagRO = 3 << 5
|
||||||
|
flagIndir = 1 << 7
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// unsafeReflectValue converts the passed reflect.Value into a one that bypasses
|
||||||
|
// the typical safety restrictions preventing access to unaddressable and
|
||||||
|
// unexported data. It works by digging the raw pointer to the underlying
|
||||||
|
// value out of the protected value and generating a new unprotected (unsafe)
|
||||||
|
// reflect.Value to it.
|
||||||
|
//
|
||||||
|
// This allows us to check for implementations of the Stringer and error
|
||||||
|
// interfaces to be used for pretty printing ordinarily unaddressable and
|
||||||
|
// inaccessible values such as unexported struct fields.
|
||||||
|
func unsafeReflectValue(v reflect.Value) (rv reflect.Value) {
|
||||||
|
indirects := 1
|
||||||
|
vt := v.Type()
|
||||||
|
upv := unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetPtr)
|
||||||
|
rvf := *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetFlag))
|
||||||
|
if rvf&flagIndir != 0 {
|
||||||
|
vt = reflect.PtrTo(v.Type())
|
||||||
|
indirects++
|
||||||
|
} else if offsetScalar != 0 {
|
||||||
|
// The value is in the scalar field when it's not one of the
|
||||||
|
// reference types.
|
||||||
|
switch vt.Kind() {
|
||||||
|
case reflect.Uintptr:
|
||||||
|
case reflect.Chan:
|
||||||
|
case reflect.Func:
|
||||||
|
case reflect.Map:
|
||||||
|
case reflect.Ptr:
|
||||||
|
case reflect.UnsafePointer:
|
||||||
|
default:
|
||||||
|
upv = unsafe.Pointer(uintptr(unsafe.Pointer(&v)) +
|
||||||
|
offsetScalar)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pv := reflect.NewAt(vt, upv)
|
||||||
|
rv = pv
|
||||||
|
for i := 0; i < indirects; i++ {
|
||||||
|
rv = rv.Elem()
|
||||||
|
}
|
||||||
|
return rv
|
||||||
|
}
|
||||||
37
Godeps/_workspace/src/github.com/davecgh/go-spew/spew/bypasssafe.go
generated
vendored
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
// Copyright (c) 2015 Dave Collins <dave@davec.name>
|
||||||
|
//
|
||||||
|
// Permission to use, copy, modify, and distribute this software for any
|
||||||
|
// purpose with or without fee is hereby granted, provided that the above
|
||||||
|
// copyright notice and this permission notice appear in all copies.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
// NOTE: Due to the following build constraints, this file will only be compiled
|
||||||
|
// when either the code is running on Google App Engine or "-tags disableunsafe"
|
||||||
|
// is added to the go build command line.
|
||||||
|
// +build appengine disableunsafe
|
||||||
|
|
||||||
|
package spew
|
||||||
|
|
||||||
|
import "reflect"
|
||||||
|
|
||||||
|
const (
|
||||||
|
// UnsafeDisabled is a build-time constant which specifies whether or
|
||||||
|
// not access to the unsafe package is available.
|
||||||
|
UnsafeDisabled = true
|
||||||
|
)
|
||||||
|
|
||||||
|
// unsafeReflectValue typically converts the passed reflect.Value into a one
|
||||||
|
// that bypasses the typical safety restrictions preventing access to
|
||||||
|
// unaddressable and unexported data. However, doing this relies on access to
|
||||||
|
// the unsafe package. This is a stub version which simply returns the passed
|
||||||
|
// reflect.Value when the unsafe package is not available.
|
||||||
|
func unsafeReflectValue(v reflect.Value) reflect.Value {
|
||||||
|
return v
|
||||||
|
}
|
||||||
135
Godeps/_workspace/src/github.com/davecgh/go-spew/spew/common.go
generated
vendored
|
|
@ -23,116 +23,8 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"unsafe"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
// ptrSize is the size of a pointer on the current arch.
|
|
||||||
ptrSize = unsafe.Sizeof((*byte)(nil))
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// offsetPtr, offsetScalar, and offsetFlag are the offsets for the
|
|
||||||
// internal reflect.Value fields. These values are valid before golang
|
|
||||||
// commit ecccf07e7f9d which changed the format. The are also valid
|
|
||||||
// after commit 82f48826c6c7 which changed the format again to mirror
|
|
||||||
// the original format. Code in the init function updates these offsets
|
|
||||||
// as necessary.
|
|
||||||
offsetPtr = uintptr(ptrSize)
|
|
||||||
offsetScalar = uintptr(0)
|
|
||||||
offsetFlag = uintptr(ptrSize * 2)
|
|
||||||
|
|
||||||
// flagKindWidth and flagKindShift indicate various bits that the
|
|
||||||
// reflect package uses internally to track kind information.
|
|
||||||
//
|
|
||||||
// flagRO indicates whether or not the value field of a reflect.Value is
|
|
||||||
// read-only.
|
|
||||||
//
|
|
||||||
// flagIndir indicates whether the value field of a reflect.Value is
|
|
||||||
// the actual data or a pointer to the data.
|
|
||||||
//
|
|
||||||
// These values are valid before golang commit 90a7c3c86944 which
|
|
||||||
// changed their positions. Code in the init function updates these
|
|
||||||
// flags as necessary.
|
|
||||||
flagKindWidth = uintptr(5)
|
|
||||||
flagKindShift = uintptr(flagKindWidth - 1)
|
|
||||||
flagRO = uintptr(1 << 0)
|
|
||||||
flagIndir = uintptr(1 << 1)
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
// Older versions of reflect.Value stored small integers directly in the
|
|
||||||
// ptr field (which is named val in the older versions). Versions
|
|
||||||
// between commits ecccf07e7f9d and 82f48826c6c7 added a new field named
|
|
||||||
// scalar for this purpose which unfortunately came before the flag
|
|
||||||
// field, so the offset of the flag field is different for those
|
|
||||||
// versions.
|
|
||||||
//
|
|
||||||
// This code constructs a new reflect.Value from a known small integer
|
|
||||||
// and checks if the size of the reflect.Value struct indicates it has
|
|
||||||
// the scalar field. When it does, the offsets are updated accordingly.
|
|
||||||
vv := reflect.ValueOf(0xf00)
|
|
||||||
if unsafe.Sizeof(vv) == (ptrSize * 4) {
|
|
||||||
offsetScalar = ptrSize * 2
|
|
||||||
offsetFlag = ptrSize * 3
|
|
||||||
}
|
|
||||||
|
|
||||||
// Commit 90a7c3c86944 changed the flag positions such that the low
|
|
||||||
// order bits are the kind. This code extracts the kind from the flags
|
|
||||||
// field and ensures it's the correct type. When it's not, the flag
|
|
||||||
// order has been changed to the newer format, so the flags are updated
|
|
||||||
// accordingly.
|
|
||||||
upf := unsafe.Pointer(uintptr(unsafe.Pointer(&vv)) + offsetFlag)
|
|
||||||
upfv := *(*uintptr)(upf)
|
|
||||||
flagKindMask := uintptr((1<<flagKindWidth - 1) << flagKindShift)
|
|
||||||
if (upfv&flagKindMask)>>flagKindShift != uintptr(reflect.Int) {
|
|
||||||
flagKindShift = 0
|
|
||||||
flagRO = 1 << 5
|
|
||||||
flagIndir = 1 << 6
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// unsafeReflectValue converts the passed reflect.Value into a one that bypasses
|
|
||||||
// the typical safety restrictions preventing access to unaddressable and
|
|
||||||
// unexported data. It works by digging the raw pointer to the underlying
|
|
||||||
// value out of the protected value and generating a new unprotected (unsafe)
|
|
||||||
// reflect.Value to it.
|
|
||||||
//
|
|
||||||
// This allows us to check for implementations of the Stringer and error
|
|
||||||
// interfaces to be used for pretty printing ordinarily unaddressable and
|
|
||||||
// inaccessible values such as unexported struct fields.
|
|
||||||
func unsafeReflectValue(v reflect.Value) (rv reflect.Value) {
|
|
||||||
indirects := 1
|
|
||||||
vt := v.Type()
|
|
||||||
upv := unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetPtr)
|
|
||||||
rvf := *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetFlag))
|
|
||||||
if rvf&flagIndir != 0 {
|
|
||||||
vt = reflect.PtrTo(v.Type())
|
|
||||||
indirects++
|
|
||||||
} else if offsetScalar != 0 {
|
|
||||||
// The value is in the scalar field when it's not one of the
|
|
||||||
// reference types.
|
|
||||||
switch vt.Kind() {
|
|
||||||
case reflect.Uintptr:
|
|
||||||
case reflect.Chan:
|
|
||||||
case reflect.Func:
|
|
||||||
case reflect.Map:
|
|
||||||
case reflect.Ptr:
|
|
||||||
case reflect.UnsafePointer:
|
|
||||||
default:
|
|
||||||
upv = unsafe.Pointer(uintptr(unsafe.Pointer(&v)) +
|
|
||||||
offsetScalar)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pv := reflect.NewAt(vt, upv)
|
|
||||||
rv = pv
|
|
||||||
for i := 0; i < indirects; i++ {
|
|
||||||
rv = rv.Elem()
|
|
||||||
}
|
|
||||||
return rv
|
|
||||||
}
|
|
||||||
|
|
||||||
// Some constants in the form of bytes to avoid string overhead. This mirrors
|
// Some constants in the form of bytes to avoid string overhead. This mirrors
|
||||||
// the technique used in the fmt package.
|
// the technique used in the fmt package.
|
||||||
var (
|
var (
|
||||||
|
|
@ -194,9 +86,14 @@ func handleMethods(cs *ConfigState, w io.Writer, v reflect.Value) (handled bool)
|
||||||
// We need an interface to check if the type implements the error or
|
// We need an interface to check if the type implements the error or
|
||||||
// Stringer interface. However, the reflect package won't give us an
|
// Stringer interface. However, the reflect package won't give us an
|
||||||
// interface on certain things like unexported struct fields in order
|
// interface on certain things like unexported struct fields in order
|
||||||
// to enforce visibility rules. We use unsafe to bypass these restrictions
|
// to enforce visibility rules. We use unsafe, when it's available,
|
||||||
// since this package does not mutate the values.
|
// to bypass these restrictions since this package does not mutate the
|
||||||
|
// values.
|
||||||
if !v.CanInterface() {
|
if !v.CanInterface() {
|
||||||
|
if UnsafeDisabled {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
v = unsafeReflectValue(v)
|
v = unsafeReflectValue(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -206,21 +103,15 @@ func handleMethods(cs *ConfigState, w io.Writer, v reflect.Value) (handled bool)
|
||||||
// mutate the value, however, types which choose to satisify an error or
|
// mutate the value, however, types which choose to satisify an error or
|
||||||
// Stringer interface with a pointer receiver should not be mutating their
|
// Stringer interface with a pointer receiver should not be mutating their
|
||||||
// state inside these interface methods.
|
// state inside these interface methods.
|
||||||
var viface interface{}
|
if !cs.DisablePointerMethods && !UnsafeDisabled && !v.CanAddr() {
|
||||||
if !cs.DisablePointerMethods {
|
v = unsafeReflectValue(v)
|
||||||
if !v.CanAddr() {
|
}
|
||||||
v = unsafeReflectValue(v)
|
if v.CanAddr() {
|
||||||
}
|
v = v.Addr()
|
||||||
viface = v.Addr().Interface()
|
|
||||||
} else {
|
|
||||||
if v.CanAddr() {
|
|
||||||
v = v.Addr()
|
|
||||||
}
|
|
||||||
viface = v.Interface()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is it an error or Stringer?
|
// Is it an error or Stringer?
|
||||||
switch iface := viface.(type) {
|
switch iface := v.Interface().(type) {
|
||||||
case error:
|
case error:
|
||||||
defer catchPanic(w, v)
|
defer catchPanic(w, v)
|
||||||
if cs.ContinueOnMethod {
|
if cs.ContinueOnMethod {
|
||||||
|
|
|
||||||
298
Godeps/_workspace/src/github.com/davecgh/go-spew/spew/common_test.go
generated
vendored
|
|
@ -1,298 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2013 Dave Collins <dave@davec.name>
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package spew_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"reflect"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
)
|
|
||||||
|
|
||||||
// custom type to test Stinger interface on non-pointer receiver.
|
|
||||||
type stringer string
|
|
||||||
|
|
||||||
// String implements the Stringer interface for testing invocation of custom
|
|
||||||
// stringers on types with non-pointer receivers.
|
|
||||||
func (s stringer) String() string {
|
|
||||||
return "stringer " + string(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
// custom type to test Stinger interface on pointer receiver.
|
|
||||||
type pstringer string
|
|
||||||
|
|
||||||
// String implements the Stringer interface for testing invocation of custom
|
|
||||||
// stringers on types with only pointer receivers.
|
|
||||||
func (s *pstringer) String() string {
|
|
||||||
return "stringer " + string(*s)
|
|
||||||
}
|
|
||||||
|
|
||||||
// xref1 and xref2 are cross referencing structs for testing circular reference
|
|
||||||
// detection.
|
|
||||||
type xref1 struct {
|
|
||||||
ps2 *xref2
|
|
||||||
}
|
|
||||||
type xref2 struct {
|
|
||||||
ps1 *xref1
|
|
||||||
}
|
|
||||||
|
|
||||||
// indirCir1, indirCir2, and indirCir3 are used to generate an indirect circular
|
|
||||||
// reference for testing detection.
|
|
||||||
type indirCir1 struct {
|
|
||||||
ps2 *indirCir2
|
|
||||||
}
|
|
||||||
type indirCir2 struct {
|
|
||||||
ps3 *indirCir3
|
|
||||||
}
|
|
||||||
type indirCir3 struct {
|
|
||||||
ps1 *indirCir1
|
|
||||||
}
|
|
||||||
|
|
||||||
// embed is used to test embedded structures.
|
|
||||||
type embed struct {
|
|
||||||
a string
|
|
||||||
}
|
|
||||||
|
|
||||||
// embedwrap is used to test embedded structures.
|
|
||||||
type embedwrap struct {
|
|
||||||
*embed
|
|
||||||
e *embed
|
|
||||||
}
|
|
||||||
|
|
||||||
// panicer is used to intentionally cause a panic for testing spew properly
|
|
||||||
// handles them
|
|
||||||
type panicer int
|
|
||||||
|
|
||||||
func (p panicer) String() string {
|
|
||||||
panic("test panic")
|
|
||||||
}
|
|
||||||
|
|
||||||
// customError is used to test custom error interface invocation.
|
|
||||||
type customError int
|
|
||||||
|
|
||||||
func (e customError) Error() string {
|
|
||||||
return fmt.Sprintf("error: %d", int(e))
|
|
||||||
}
|
|
||||||
|
|
||||||
// stringizeWants converts a slice of wanted test output into a format suitable
|
|
||||||
// for a test error message.
|
|
||||||
func stringizeWants(wants []string) string {
|
|
||||||
s := ""
|
|
||||||
for i, want := range wants {
|
|
||||||
if i > 0 {
|
|
||||||
s += fmt.Sprintf("want%d: %s", i+1, want)
|
|
||||||
} else {
|
|
||||||
s += "want: " + want
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
// testFailed returns whether or not a test failed by checking if the result
|
|
||||||
// of the test is in the slice of wanted strings.
|
|
||||||
func testFailed(result string, wants []string) bool {
|
|
||||||
for _, want := range wants {
|
|
||||||
if result == want {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
type sortableStruct struct {
|
|
||||||
x int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ss sortableStruct) String() string {
|
|
||||||
return fmt.Sprintf("ss.%d", ss.x)
|
|
||||||
}
|
|
||||||
|
|
||||||
type unsortableStruct struct {
|
|
||||||
x int
|
|
||||||
}
|
|
||||||
|
|
||||||
type sortTestCase struct {
|
|
||||||
input []reflect.Value
|
|
||||||
expected []reflect.Value
|
|
||||||
}
|
|
||||||
|
|
||||||
func helpTestSortValues(tests []sortTestCase, cs *spew.ConfigState, t *testing.T) {
|
|
||||||
getInterfaces := func(values []reflect.Value) []interface{} {
|
|
||||||
interfaces := []interface{}{}
|
|
||||||
for _, v := range values {
|
|
||||||
interfaces = append(interfaces, v.Interface())
|
|
||||||
}
|
|
||||||
return interfaces
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, test := range tests {
|
|
||||||
spew.SortValues(test.input, cs)
|
|
||||||
// reflect.DeepEqual cannot really make sense of reflect.Value,
|
|
||||||
// probably because of all the pointer tricks. For instance,
|
|
||||||
// v(2.0) != v(2.0) on a 32-bits system. Turn them into interface{}
|
|
||||||
// instead.
|
|
||||||
input := getInterfaces(test.input)
|
|
||||||
expected := getInterfaces(test.expected)
|
|
||||||
if !reflect.DeepEqual(input, expected) {
|
|
||||||
t.Errorf("Sort mismatch:\n %v != %v", input, expected)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestSortValues ensures the sort functionality for relect.Value based sorting
|
|
||||||
// works as intended.
|
|
||||||
func TestSortValues(t *testing.T) {
|
|
||||||
v := reflect.ValueOf
|
|
||||||
|
|
||||||
a := v("a")
|
|
||||||
b := v("b")
|
|
||||||
c := v("c")
|
|
||||||
embedA := v(embed{"a"})
|
|
||||||
embedB := v(embed{"b"})
|
|
||||||
embedC := v(embed{"c"})
|
|
||||||
tests := []sortTestCase{
|
|
||||||
// No values.
|
|
||||||
{
|
|
||||||
[]reflect.Value{},
|
|
||||||
[]reflect.Value{},
|
|
||||||
},
|
|
||||||
// Bools.
|
|
||||||
{
|
|
||||||
[]reflect.Value{v(false), v(true), v(false)},
|
|
||||||
[]reflect.Value{v(false), v(false), v(true)},
|
|
||||||
},
|
|
||||||
// Ints.
|
|
||||||
{
|
|
||||||
[]reflect.Value{v(2), v(1), v(3)},
|
|
||||||
[]reflect.Value{v(1), v(2), v(3)},
|
|
||||||
},
|
|
||||||
// Uints.
|
|
||||||
{
|
|
||||||
[]reflect.Value{v(uint8(2)), v(uint8(1)), v(uint8(3))},
|
|
||||||
[]reflect.Value{v(uint8(1)), v(uint8(2)), v(uint8(3))},
|
|
||||||
},
|
|
||||||
// Floats.
|
|
||||||
{
|
|
||||||
[]reflect.Value{v(2.0), v(1.0), v(3.0)},
|
|
||||||
[]reflect.Value{v(1.0), v(2.0), v(3.0)},
|
|
||||||
},
|
|
||||||
// Strings.
|
|
||||||
{
|
|
||||||
[]reflect.Value{b, a, c},
|
|
||||||
[]reflect.Value{a, b, c},
|
|
||||||
},
|
|
||||||
// Array
|
|
||||||
{
|
|
||||||
[]reflect.Value{v([3]int{3, 2, 1}), v([3]int{1, 3, 2}), v([3]int{1, 2, 3})},
|
|
||||||
[]reflect.Value{v([3]int{1, 2, 3}), v([3]int{1, 3, 2}), v([3]int{3, 2, 1})},
|
|
||||||
},
|
|
||||||
// Uintptrs.
|
|
||||||
{
|
|
||||||
[]reflect.Value{v(uintptr(2)), v(uintptr(1)), v(uintptr(3))},
|
|
||||||
[]reflect.Value{v(uintptr(1)), v(uintptr(2)), v(uintptr(3))},
|
|
||||||
},
|
|
||||||
// SortableStructs.
|
|
||||||
{
|
|
||||||
// Note: not sorted - DisableMethods is set.
|
|
||||||
[]reflect.Value{v(sortableStruct{2}), v(sortableStruct{1}), v(sortableStruct{3})},
|
|
||||||
[]reflect.Value{v(sortableStruct{2}), v(sortableStruct{1}), v(sortableStruct{3})},
|
|
||||||
},
|
|
||||||
// UnsortableStructs.
|
|
||||||
{
|
|
||||||
// Note: not sorted - SpewKeys is false.
|
|
||||||
[]reflect.Value{v(unsortableStruct{2}), v(unsortableStruct{1}), v(unsortableStruct{3})},
|
|
||||||
[]reflect.Value{v(unsortableStruct{2}), v(unsortableStruct{1}), v(unsortableStruct{3})},
|
|
||||||
},
|
|
||||||
// Invalid.
|
|
||||||
{
|
|
||||||
[]reflect.Value{embedB, embedA, embedC},
|
|
||||||
[]reflect.Value{embedB, embedA, embedC},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
cs := spew.ConfigState{DisableMethods: true, SpewKeys: false}
|
|
||||||
helpTestSortValues(tests, &cs, t)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestSortValuesWithMethods ensures the sort functionality for relect.Value
|
|
||||||
// based sorting works as intended when using string methods.
|
|
||||||
func TestSortValuesWithMethods(t *testing.T) {
|
|
||||||
v := reflect.ValueOf
|
|
||||||
|
|
||||||
a := v("a")
|
|
||||||
b := v("b")
|
|
||||||
c := v("c")
|
|
||||||
tests := []sortTestCase{
|
|
||||||
// Ints.
|
|
||||||
{
|
|
||||||
[]reflect.Value{v(2), v(1), v(3)},
|
|
||||||
[]reflect.Value{v(1), v(2), v(3)},
|
|
||||||
},
|
|
||||||
// Strings.
|
|
||||||
{
|
|
||||||
[]reflect.Value{b, a, c},
|
|
||||||
[]reflect.Value{a, b, c},
|
|
||||||
},
|
|
||||||
// SortableStructs.
|
|
||||||
{
|
|
||||||
[]reflect.Value{v(sortableStruct{2}), v(sortableStruct{1}), v(sortableStruct{3})},
|
|
||||||
[]reflect.Value{v(sortableStruct{1}), v(sortableStruct{2}), v(sortableStruct{3})},
|
|
||||||
},
|
|
||||||
// UnsortableStructs.
|
|
||||||
{
|
|
||||||
// Note: not sorted - SpewKeys is false.
|
|
||||||
[]reflect.Value{v(unsortableStruct{2}), v(unsortableStruct{1}), v(unsortableStruct{3})},
|
|
||||||
[]reflect.Value{v(unsortableStruct{2}), v(unsortableStruct{1}), v(unsortableStruct{3})},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
cs := spew.ConfigState{DisableMethods: false, SpewKeys: false}
|
|
||||||
helpTestSortValues(tests, &cs, t)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestSortValuesWithSpew ensures the sort functionality for relect.Value
|
|
||||||
// based sorting works as intended when using spew to stringify keys.
|
|
||||||
func TestSortValuesWithSpew(t *testing.T) {
|
|
||||||
v := reflect.ValueOf
|
|
||||||
|
|
||||||
a := v("a")
|
|
||||||
b := v("b")
|
|
||||||
c := v("c")
|
|
||||||
tests := []sortTestCase{
|
|
||||||
// Ints.
|
|
||||||
{
|
|
||||||
[]reflect.Value{v(2), v(1), v(3)},
|
|
||||||
[]reflect.Value{v(1), v(2), v(3)},
|
|
||||||
},
|
|
||||||
// Strings.
|
|
||||||
{
|
|
||||||
[]reflect.Value{b, a, c},
|
|
||||||
[]reflect.Value{a, b, c},
|
|
||||||
},
|
|
||||||
// SortableStructs.
|
|
||||||
{
|
|
||||||
[]reflect.Value{v(sortableStruct{2}), v(sortableStruct{1}), v(sortableStruct{3})},
|
|
||||||
[]reflect.Value{v(sortableStruct{1}), v(sortableStruct{2}), v(sortableStruct{3})},
|
|
||||||
},
|
|
||||||
// UnsortableStructs.
|
|
||||||
{
|
|
||||||
[]reflect.Value{v(unsortableStruct{2}), v(unsortableStruct{1}), v(unsortableStruct{3})},
|
|
||||||
[]reflect.Value{v(unsortableStruct{1}), v(unsortableStruct{2}), v(unsortableStruct{3})},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
cs := spew.ConfigState{DisableMethods: true, SpewKeys: true}
|
|
||||||
helpTestSortValues(tests, &cs, t)
|
|
||||||
}
|
|
||||||
5
Godeps/_workspace/src/github.com/davecgh/go-spew/spew/config.go
generated
vendored
|
|
@ -61,7 +61,10 @@ type ConfigState struct {
|
||||||
// with a pointer receiver could technically mutate the value, however,
|
// with a pointer receiver could technically mutate the value, however,
|
||||||
// in practice, types which choose to satisify an error or Stringer
|
// in practice, types which choose to satisify an error or Stringer
|
||||||
// interface with a pointer receiver should not be mutating their state
|
// interface with a pointer receiver should not be mutating their state
|
||||||
// inside these interface methods.
|
// inside these interface methods. As a result, this option relies on
|
||||||
|
// access to the unsafe package, so it will not have any effect when
|
||||||
|
// running in environments without access to the unsafe package such as
|
||||||
|
// Google App Engine or with the "disableunsafe" build tag specified.
|
||||||
DisablePointerMethods bool
|
DisablePointerMethods bool
|
||||||
|
|
||||||
// ContinueOnMethod specifies whether or not recursion should continue once
|
// ContinueOnMethod specifies whether or not recursion should continue once
|
||||||
|
|
|
||||||
29
Godeps/_workspace/src/github.com/davecgh/go-spew/spew/dump.go
generated
vendored
|
|
@ -181,25 +181,28 @@ func (d *dumpState) dumpSlice(v reflect.Value) {
|
||||||
// Try to use existing uint8 slices and fall back to converting
|
// Try to use existing uint8 slices and fall back to converting
|
||||||
// and copying if that fails.
|
// and copying if that fails.
|
||||||
case vt.Kind() == reflect.Uint8:
|
case vt.Kind() == reflect.Uint8:
|
||||||
// We need an addressable interface to convert the type back
|
// We need an addressable interface to convert the type
|
||||||
// into a byte slice. However, the reflect package won't give
|
// to a byte slice. However, the reflect package won't
|
||||||
// us an interface on certain things like unexported struct
|
// give us an interface on certain things like
|
||||||
// fields in order to enforce visibility rules. We use unsafe
|
// unexported struct fields in order to enforce
|
||||||
// to bypass these restrictions since this package does not
|
// visibility rules. We use unsafe, when available, to
|
||||||
|
// bypass these restrictions since this package does not
|
||||||
// mutate the values.
|
// mutate the values.
|
||||||
vs := v
|
vs := v
|
||||||
if !vs.CanInterface() || !vs.CanAddr() {
|
if !vs.CanInterface() || !vs.CanAddr() {
|
||||||
vs = unsafeReflectValue(vs)
|
vs = unsafeReflectValue(vs)
|
||||||
}
|
}
|
||||||
vs = vs.Slice(0, numEntries)
|
if !UnsafeDisabled {
|
||||||
|
vs = vs.Slice(0, numEntries)
|
||||||
|
|
||||||
// Use the existing uint8 slice if it can be type
|
// Use the existing uint8 slice if it can be
|
||||||
// asserted.
|
// type asserted.
|
||||||
iface := vs.Interface()
|
iface := vs.Interface()
|
||||||
if slice, ok := iface.([]uint8); ok {
|
if slice, ok := iface.([]uint8); ok {
|
||||||
buf = slice
|
buf = slice
|
||||||
doHexDump = true
|
doHexDump = true
|
||||||
break
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The underlying data needs to be converted if it can't
|
// The underlying data needs to be converted if it can't
|
||||||
|
|
|
||||||
1021
Godeps/_workspace/src/github.com/davecgh/go-spew/spew/dump_test.go
generated
vendored
97
Godeps/_workspace/src/github.com/davecgh/go-spew/spew/dumpcgo_test.go
generated
vendored
|
|
@ -1,97 +0,0 @@
|
||||||
// Copyright (c) 2013 Dave Collins <dave@davec.name>
|
|
||||||
//
|
|
||||||
// Permission to use, copy, modify, and distribute this software for any
|
|
||||||
// purpose with or without fee is hereby granted, provided that the above
|
|
||||||
// copyright notice and this permission notice appear in all copies.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
|
|
||||||
// NOTE: Due to the following build constraints, this file will only be compiled
|
|
||||||
// when both cgo is supported and "-tags testcgo" is added to the go test
|
|
||||||
// command line. This means the cgo tests are only added (and hence run) when
|
|
||||||
// specifially requested. This configuration is used because spew itself
|
|
||||||
// does not require cgo to run even though it does handle certain cgo types
|
|
||||||
// specially. Rather than forcing all clients to require cgo and an external
|
|
||||||
// C compiler just to run the tests, this scheme makes them optional.
|
|
||||||
// +build cgo,testcgo
|
|
||||||
|
|
||||||
package spew_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/davecgh/go-spew/spew/testdata"
|
|
||||||
)
|
|
||||||
|
|
||||||
func addCgoDumpTests() {
|
|
||||||
// C char pointer.
|
|
||||||
v := testdata.GetCgoCharPointer()
|
|
||||||
nv := testdata.GetCgoNullCharPointer()
|
|
||||||
pv := &v
|
|
||||||
vcAddr := fmt.Sprintf("%p", v)
|
|
||||||
vAddr := fmt.Sprintf("%p", pv)
|
|
||||||
pvAddr := fmt.Sprintf("%p", &pv)
|
|
||||||
vt := "*testdata._Ctype_char"
|
|
||||||
vs := "116"
|
|
||||||
addDumpTest(v, "("+vt+")("+vcAddr+")("+vs+")\n")
|
|
||||||
addDumpTest(pv, "(*"+vt+")("+vAddr+"->"+vcAddr+")("+vs+")\n")
|
|
||||||
addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+"->"+vcAddr+")("+vs+")\n")
|
|
||||||
addDumpTest(nv, "("+vt+")(<nil>)\n")
|
|
||||||
|
|
||||||
// C char array.
|
|
||||||
v2, v2l, v2c := testdata.GetCgoCharArray()
|
|
||||||
v2Len := fmt.Sprintf("%d", v2l)
|
|
||||||
v2Cap := fmt.Sprintf("%d", v2c)
|
|
||||||
v2t := "[6]testdata._Ctype_char"
|
|
||||||
v2s := "(len=" + v2Len + " cap=" + v2Cap + ") " +
|
|
||||||
"{\n 00000000 74 65 73 74 32 00 " +
|
|
||||||
" |test2.|\n}"
|
|
||||||
addDumpTest(v2, "("+v2t+") "+v2s+"\n")
|
|
||||||
|
|
||||||
// C unsigned char array.
|
|
||||||
v3, v3l, v3c := testdata.GetCgoUnsignedCharArray()
|
|
||||||
v3Len := fmt.Sprintf("%d", v3l)
|
|
||||||
v3Cap := fmt.Sprintf("%d", v3c)
|
|
||||||
v3t := "[6]testdata._Ctype_unsignedchar"
|
|
||||||
v3s := "(len=" + v3Len + " cap=" + v3Cap + ") " +
|
|
||||||
"{\n 00000000 74 65 73 74 33 00 " +
|
|
||||||
" |test3.|\n}"
|
|
||||||
addDumpTest(v3, "("+v3t+") "+v3s+"\n")
|
|
||||||
|
|
||||||
// C signed char array.
|
|
||||||
v4, v4l, v4c := testdata.GetCgoSignedCharArray()
|
|
||||||
v4Len := fmt.Sprintf("%d", v4l)
|
|
||||||
v4Cap := fmt.Sprintf("%d", v4c)
|
|
||||||
v4t := "[6]testdata._Ctype_schar"
|
|
||||||
v4t2 := "testdata._Ctype_schar"
|
|
||||||
v4s := "(len=" + v4Len + " cap=" + v4Cap + ") " +
|
|
||||||
"{\n (" + v4t2 + ") 116,\n (" + v4t2 + ") 101,\n (" + v4t2 +
|
|
||||||
") 115,\n (" + v4t2 + ") 116,\n (" + v4t2 + ") 52,\n (" + v4t2 +
|
|
||||||
") 0\n}"
|
|
||||||
addDumpTest(v4, "("+v4t+") "+v4s+"\n")
|
|
||||||
|
|
||||||
// C uint8_t array.
|
|
||||||
v5, v5l, v5c := testdata.GetCgoUint8tArray()
|
|
||||||
v5Len := fmt.Sprintf("%d", v5l)
|
|
||||||
v5Cap := fmt.Sprintf("%d", v5c)
|
|
||||||
v5t := "[6]testdata._Ctype_uint8_t"
|
|
||||||
v5s := "(len=" + v5Len + " cap=" + v5Cap + ") " +
|
|
||||||
"{\n 00000000 74 65 73 74 35 00 " +
|
|
||||||
" |test5.|\n}"
|
|
||||||
addDumpTest(v5, "("+v5t+") "+v5s+"\n")
|
|
||||||
|
|
||||||
// C typedefed unsigned char array.
|
|
||||||
v6, v6l, v6c := testdata.GetCgoTypdefedUnsignedCharArray()
|
|
||||||
v6Len := fmt.Sprintf("%d", v6l)
|
|
||||||
v6Cap := fmt.Sprintf("%d", v6c)
|
|
||||||
v6t := "[6]testdata._Ctype_custom_uchar_t"
|
|
||||||
v6s := "(len=" + v6Len + " cap=" + v6Cap + ") " +
|
|
||||||
"{\n 00000000 74 65 73 74 36 00 " +
|
|
||||||
" |test6.|\n}"
|
|
||||||
addDumpTest(v6, "("+v6t+") "+v6s+"\n")
|
|
||||||
}
|
|
||||||
26
Godeps/_workspace/src/github.com/davecgh/go-spew/spew/dumpnocgo_test.go
generated
vendored
|
|
@ -1,26 +0,0 @@
|
||||||
// Copyright (c) 2013 Dave Collins <dave@davec.name>
|
|
||||||
//
|
|
||||||
// Permission to use, copy, modify, and distribute this software for any
|
|
||||||
// purpose with or without fee is hereby granted, provided that the above
|
|
||||||
// copyright notice and this permission notice appear in all copies.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
|
|
||||||
// NOTE: Due to the following build constraints, this file will only be compiled
|
|
||||||
// when either cgo is not supported or "-tags testcgo" is not added to the go
|
|
||||||
// test command line. This file intentionally does not setup any cgo tests in
|
|
||||||
// this scenario.
|
|
||||||
// +build !cgo !testcgo
|
|
||||||
|
|
||||||
package spew_test
|
|
||||||
|
|
||||||
func addCgoDumpTests() {
|
|
||||||
// Don't add any tests for cgo since this file is only compiled when
|
|
||||||
// there should not be any cgo tests.
|
|
||||||
}
|
|
||||||
230
Godeps/_workspace/src/github.com/davecgh/go-spew/spew/example_test.go
generated
vendored
|
|
@ -1,230 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2013 Dave Collins <dave@davec.name>
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package spew_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Flag int
|
|
||||||
|
|
||||||
const (
|
|
||||||
flagOne Flag = iota
|
|
||||||
flagTwo
|
|
||||||
)
|
|
||||||
|
|
||||||
var flagStrings = map[Flag]string{
|
|
||||||
flagOne: "flagOne",
|
|
||||||
flagTwo: "flagTwo",
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f Flag) String() string {
|
|
||||||
if s, ok := flagStrings[f]; ok {
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("Unknown flag (%d)", int(f))
|
|
||||||
}
|
|
||||||
|
|
||||||
type Bar struct {
|
|
||||||
flag Flag
|
|
||||||
data uintptr
|
|
||||||
}
|
|
||||||
|
|
||||||
type Foo struct {
|
|
||||||
unexportedField Bar
|
|
||||||
ExportedField map[interface{}]interface{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This example demonstrates how to use Dump to dump variables to stdout.
|
|
||||||
func ExampleDump() {
|
|
||||||
// The following package level declarations are assumed for this example:
|
|
||||||
/*
|
|
||||||
type Flag int
|
|
||||||
|
|
||||||
const (
|
|
||||||
flagOne Flag = iota
|
|
||||||
flagTwo
|
|
||||||
)
|
|
||||||
|
|
||||||
var flagStrings = map[Flag]string{
|
|
||||||
flagOne: "flagOne",
|
|
||||||
flagTwo: "flagTwo",
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f Flag) String() string {
|
|
||||||
if s, ok := flagStrings[f]; ok {
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("Unknown flag (%d)", int(f))
|
|
||||||
}
|
|
||||||
|
|
||||||
type Bar struct {
|
|
||||||
flag Flag
|
|
||||||
data uintptr
|
|
||||||
}
|
|
||||||
|
|
||||||
type Foo struct {
|
|
||||||
unexportedField Bar
|
|
||||||
ExportedField map[interface{}]interface{}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Setup some sample data structures for the example.
|
|
||||||
bar := Bar{Flag(flagTwo), uintptr(0)}
|
|
||||||
s1 := Foo{bar, map[interface{}]interface{}{"one": true}}
|
|
||||||
f := Flag(5)
|
|
||||||
b := []byte{
|
|
||||||
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
|
|
||||||
0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
|
|
||||||
0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
|
|
||||||
0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
|
|
||||||
0x31, 0x32,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dump!
|
|
||||||
spew.Dump(s1, f, b)
|
|
||||||
|
|
||||||
// Output:
|
|
||||||
// (spew_test.Foo) {
|
|
||||||
// unexportedField: (spew_test.Bar) {
|
|
||||||
// flag: (spew_test.Flag) flagTwo,
|
|
||||||
// data: (uintptr) <nil>
|
|
||||||
// },
|
|
||||||
// ExportedField: (map[interface {}]interface {}) (len=1) {
|
|
||||||
// (string) (len=3) "one": (bool) true
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// (spew_test.Flag) Unknown flag (5)
|
|
||||||
// ([]uint8) (len=34 cap=34) {
|
|
||||||
// 00000000 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 |............... |
|
|
||||||
// 00000010 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 |!"#$%&'()*+,-./0|
|
|
||||||
// 00000020 31 32 |12|
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
// This example demonstrates how to use Printf to display a variable with a
|
|
||||||
// format string and inline formatting.
|
|
||||||
func ExamplePrintf() {
|
|
||||||
// Create a double pointer to a uint 8.
|
|
||||||
ui8 := uint8(5)
|
|
||||||
pui8 := &ui8
|
|
||||||
ppui8 := &pui8
|
|
||||||
|
|
||||||
// Create a circular data type.
|
|
||||||
type circular struct {
|
|
||||||
ui8 uint8
|
|
||||||
c *circular
|
|
||||||
}
|
|
||||||
c := circular{ui8: 1}
|
|
||||||
c.c = &c
|
|
||||||
|
|
||||||
// Print!
|
|
||||||
spew.Printf("ppui8: %v\n", ppui8)
|
|
||||||
spew.Printf("circular: %v\n", c)
|
|
||||||
|
|
||||||
// Output:
|
|
||||||
// ppui8: <**>5
|
|
||||||
// circular: {1 <*>{1 <*><shown>}}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This example demonstrates how to use a ConfigState.
|
|
||||||
func ExampleConfigState() {
|
|
||||||
// Modify the indent level of the ConfigState only. The global
|
|
||||||
// configuration is not modified.
|
|
||||||
scs := spew.ConfigState{Indent: "\t"}
|
|
||||||
|
|
||||||
// Output using the ConfigState instance.
|
|
||||||
v := map[string]int{"one": 1}
|
|
||||||
scs.Printf("v: %v\n", v)
|
|
||||||
scs.Dump(v)
|
|
||||||
|
|
||||||
// Output:
|
|
||||||
// v: map[one:1]
|
|
||||||
// (map[string]int) (len=1) {
|
|
||||||
// (string) (len=3) "one": (int) 1
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
// This example demonstrates how to use ConfigState.Dump to dump variables to
|
|
||||||
// stdout
|
|
||||||
func ExampleConfigState_Dump() {
|
|
||||||
// See the top-level Dump example for details on the types used in this
|
|
||||||
// example.
|
|
||||||
|
|
||||||
// Create two ConfigState instances with different indentation.
|
|
||||||
scs := spew.ConfigState{Indent: "\t"}
|
|
||||||
scs2 := spew.ConfigState{Indent: " "}
|
|
||||||
|
|
||||||
// Setup some sample data structures for the example.
|
|
||||||
bar := Bar{Flag(flagTwo), uintptr(0)}
|
|
||||||
s1 := Foo{bar, map[interface{}]interface{}{"one": true}}
|
|
||||||
|
|
||||||
// Dump using the ConfigState instances.
|
|
||||||
scs.Dump(s1)
|
|
||||||
scs2.Dump(s1)
|
|
||||||
|
|
||||||
// Output:
|
|
||||||
// (spew_test.Foo) {
|
|
||||||
// unexportedField: (spew_test.Bar) {
|
|
||||||
// flag: (spew_test.Flag) flagTwo,
|
|
||||||
// data: (uintptr) <nil>
|
|
||||||
// },
|
|
||||||
// ExportedField: (map[interface {}]interface {}) (len=1) {
|
|
||||||
// (string) (len=3) "one": (bool) true
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// (spew_test.Foo) {
|
|
||||||
// unexportedField: (spew_test.Bar) {
|
|
||||||
// flag: (spew_test.Flag) flagTwo,
|
|
||||||
// data: (uintptr) <nil>
|
|
||||||
// },
|
|
||||||
// ExportedField: (map[interface {}]interface {}) (len=1) {
|
|
||||||
// (string) (len=3) "one": (bool) true
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
// This example demonstrates how to use ConfigState.Printf to display a variable
|
|
||||||
// with a format string and inline formatting.
|
|
||||||
func ExampleConfigState_Printf() {
|
|
||||||
// See the top-level Dump example for details on the types used in this
|
|
||||||
// example.
|
|
||||||
|
|
||||||
// Create two ConfigState instances and modify the method handling of the
|
|
||||||
// first ConfigState only.
|
|
||||||
scs := spew.NewDefaultConfig()
|
|
||||||
scs2 := spew.NewDefaultConfig()
|
|
||||||
scs.DisableMethods = true
|
|
||||||
|
|
||||||
// Alternatively
|
|
||||||
// scs := spew.ConfigState{Indent: " ", DisableMethods: true}
|
|
||||||
// scs2 := spew.ConfigState{Indent: " "}
|
|
||||||
|
|
||||||
// This is of type Flag which implements a Stringer and has raw value 1.
|
|
||||||
f := flagTwo
|
|
||||||
|
|
||||||
// Dump using the ConfigState instances.
|
|
||||||
scs.Printf("f: %v\n", f)
|
|
||||||
scs2.Printf("f: %v\n", f)
|
|
||||||
|
|
||||||
// Output:
|
|
||||||
// f: 1
|
|
||||||
// f: flagTwo
|
|
||||||
}
|
|
||||||
1535
Godeps/_workspace/src/github.com/davecgh/go-spew/spew/format_test.go
generated
vendored
156
Godeps/_workspace/src/github.com/davecgh/go-spew/spew/internal_test.go
generated
vendored
|
|
@ -1,156 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2013 Dave Collins <dave@davec.name>
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
This test file is part of the spew package rather than than the spew_test
|
|
||||||
package because it needs access to internals to properly test certain cases
|
|
||||||
which are not possible via the public interface since they should never happen.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package spew
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"reflect"
|
|
||||||
"testing"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
// dummyFmtState implements a fake fmt.State to use for testing invalid
|
|
||||||
// reflect.Value handling. This is necessary because the fmt package catches
|
|
||||||
// invalid values before invoking the formatter on them.
|
|
||||||
type dummyFmtState struct {
|
|
||||||
bytes.Buffer
|
|
||||||
}
|
|
||||||
|
|
||||||
func (dfs *dummyFmtState) Flag(f int) bool {
|
|
||||||
if f == int('+') {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (dfs *dummyFmtState) Precision() (int, bool) {
|
|
||||||
return 0, false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (dfs *dummyFmtState) Width() (int, bool) {
|
|
||||||
return 0, false
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestInvalidReflectValue ensures the dump and formatter code handles an
|
|
||||||
// invalid reflect value properly. This needs access to internal state since it
|
|
||||||
// should never happen in real code and therefore can't be tested via the public
|
|
||||||
// API.
|
|
||||||
func TestInvalidReflectValue(t *testing.T) {
|
|
||||||
i := 1
|
|
||||||
|
|
||||||
// Dump invalid reflect value.
|
|
||||||
v := new(reflect.Value)
|
|
||||||
buf := new(bytes.Buffer)
|
|
||||||
d := dumpState{w: buf, cs: &Config}
|
|
||||||
d.dump(*v)
|
|
||||||
s := buf.String()
|
|
||||||
want := "<invalid>"
|
|
||||||
if s != want {
|
|
||||||
t.Errorf("InvalidReflectValue #%d\n got: %s want: %s", i, s, want)
|
|
||||||
}
|
|
||||||
i++
|
|
||||||
|
|
||||||
// Formatter invalid reflect value.
|
|
||||||
buf2 := new(dummyFmtState)
|
|
||||||
f := formatState{value: *v, cs: &Config, fs: buf2}
|
|
||||||
f.format(*v)
|
|
||||||
s = buf2.String()
|
|
||||||
want = "<invalid>"
|
|
||||||
if s != want {
|
|
||||||
t.Errorf("InvalidReflectValue #%d got: %s want: %s", i, s, want)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// changeKind uses unsafe to intentionally change the kind of a reflect.Value to
|
|
||||||
// the maximum kind value which does not exist. This is needed to test the
|
|
||||||
// fallback code which punts to the standard fmt library for new types that
|
|
||||||
// might get added to the language.
|
|
||||||
func changeKind(v *reflect.Value, readOnly bool) {
|
|
||||||
rvf := (*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(v)) + offsetFlag))
|
|
||||||
*rvf = *rvf | ((1<<flagKindWidth - 1) << flagKindShift)
|
|
||||||
if readOnly {
|
|
||||||
*rvf |= flagRO
|
|
||||||
} else {
|
|
||||||
*rvf &= ^uintptr(flagRO)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestAddedReflectValue tests functionaly of the dump and formatter code which
|
|
||||||
// falls back to the standard fmt library for new types that might get added to
|
|
||||||
// the language.
|
|
||||||
func TestAddedReflectValue(t *testing.T) {
|
|
||||||
i := 1
|
|
||||||
|
|
||||||
// Dump using a reflect.Value that is exported.
|
|
||||||
v := reflect.ValueOf(int8(5))
|
|
||||||
changeKind(&v, false)
|
|
||||||
buf := new(bytes.Buffer)
|
|
||||||
d := dumpState{w: buf, cs: &Config}
|
|
||||||
d.dump(v)
|
|
||||||
s := buf.String()
|
|
||||||
want := "(int8) 5"
|
|
||||||
if s != want {
|
|
||||||
t.Errorf("TestAddedReflectValue #%d\n got: %s want: %s", i, s, want)
|
|
||||||
}
|
|
||||||
i++
|
|
||||||
|
|
||||||
// Dump using a reflect.Value that is not exported.
|
|
||||||
changeKind(&v, true)
|
|
||||||
buf.Reset()
|
|
||||||
d.dump(v)
|
|
||||||
s = buf.String()
|
|
||||||
want = "(int8) <int8 Value>"
|
|
||||||
if s != want {
|
|
||||||
t.Errorf("TestAddedReflectValue #%d\n got: %s want: %s", i, s, want)
|
|
||||||
}
|
|
||||||
i++
|
|
||||||
|
|
||||||
// Formatter using a reflect.Value that is exported.
|
|
||||||
changeKind(&v, false)
|
|
||||||
buf2 := new(dummyFmtState)
|
|
||||||
f := formatState{value: v, cs: &Config, fs: buf2}
|
|
||||||
f.format(v)
|
|
||||||
s = buf2.String()
|
|
||||||
want = "5"
|
|
||||||
if s != want {
|
|
||||||
t.Errorf("TestAddedReflectValue #%d got: %s want: %s", i, s, want)
|
|
||||||
}
|
|
||||||
i++
|
|
||||||
|
|
||||||
// Formatter using a reflect.Value that is not exported.
|
|
||||||
changeKind(&v, true)
|
|
||||||
buf2.Reset()
|
|
||||||
f = formatState{value: v, cs: &Config, fs: buf2}
|
|
||||||
f.format(v)
|
|
||||||
s = buf2.String()
|
|
||||||
want = "<int8 Value>"
|
|
||||||
if s != want {
|
|
||||||
t.Errorf("TestAddedReflectValue #%d got: %s want: %s", i, s, want)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SortValues makes the internal sortValues function available to the test
|
|
||||||
// package.
|
|
||||||
func SortValues(values []reflect.Value, cs *ConfigState) {
|
|
||||||
sortValues(values, cs)
|
|
||||||
}
|
|
||||||
308
Godeps/_workspace/src/github.com/davecgh/go-spew/spew/spew_test.go
generated
vendored
|
|
@ -1,308 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2013 Dave Collins <dave@davec.name>
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package spew_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
// spewFunc is used to identify which public function of the spew package or
|
|
||||||
// ConfigState a test applies to.
|
|
||||||
type spewFunc int
|
|
||||||
|
|
||||||
const (
|
|
||||||
fCSFdump spewFunc = iota
|
|
||||||
fCSFprint
|
|
||||||
fCSFprintf
|
|
||||||
fCSFprintln
|
|
||||||
fCSPrint
|
|
||||||
fCSPrintln
|
|
||||||
fCSSdump
|
|
||||||
fCSSprint
|
|
||||||
fCSSprintf
|
|
||||||
fCSSprintln
|
|
||||||
fCSErrorf
|
|
||||||
fCSNewFormatter
|
|
||||||
fErrorf
|
|
||||||
fFprint
|
|
||||||
fFprintln
|
|
||||||
fPrint
|
|
||||||
fPrintln
|
|
||||||
fSdump
|
|
||||||
fSprint
|
|
||||||
fSprintf
|
|
||||||
fSprintln
|
|
||||||
)
|
|
||||||
|
|
||||||
// Map of spewFunc values to names for pretty printing.
|
|
||||||
var spewFuncStrings = map[spewFunc]string{
|
|
||||||
fCSFdump: "ConfigState.Fdump",
|
|
||||||
fCSFprint: "ConfigState.Fprint",
|
|
||||||
fCSFprintf: "ConfigState.Fprintf",
|
|
||||||
fCSFprintln: "ConfigState.Fprintln",
|
|
||||||
fCSSdump: "ConfigState.Sdump",
|
|
||||||
fCSPrint: "ConfigState.Print",
|
|
||||||
fCSPrintln: "ConfigState.Println",
|
|
||||||
fCSSprint: "ConfigState.Sprint",
|
|
||||||
fCSSprintf: "ConfigState.Sprintf",
|
|
||||||
fCSSprintln: "ConfigState.Sprintln",
|
|
||||||
fCSErrorf: "ConfigState.Errorf",
|
|
||||||
fCSNewFormatter: "ConfigState.NewFormatter",
|
|
||||||
fErrorf: "spew.Errorf",
|
|
||||||
fFprint: "spew.Fprint",
|
|
||||||
fFprintln: "spew.Fprintln",
|
|
||||||
fPrint: "spew.Print",
|
|
||||||
fPrintln: "spew.Println",
|
|
||||||
fSdump: "spew.Sdump",
|
|
||||||
fSprint: "spew.Sprint",
|
|
||||||
fSprintf: "spew.Sprintf",
|
|
||||||
fSprintln: "spew.Sprintln",
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f spewFunc) String() string {
|
|
||||||
if s, ok := spewFuncStrings[f]; ok {
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("Unknown spewFunc (%d)", int(f))
|
|
||||||
}
|
|
||||||
|
|
||||||
// spewTest is used to describe a test to be performed against the public
|
|
||||||
// functions of the spew package or ConfigState.
|
|
||||||
type spewTest struct {
|
|
||||||
cs *spew.ConfigState
|
|
||||||
f spewFunc
|
|
||||||
format string
|
|
||||||
in interface{}
|
|
||||||
want string
|
|
||||||
}
|
|
||||||
|
|
||||||
// spewTests houses the tests to be performed against the public functions of
|
|
||||||
// the spew package and ConfigState.
|
|
||||||
//
|
|
||||||
// These tests are only intended to ensure the public functions are exercised
|
|
||||||
// and are intentionally not exhaustive of types. The exhaustive type
|
|
||||||
// tests are handled in the dump and format tests.
|
|
||||||
var spewTests []spewTest
|
|
||||||
|
|
||||||
// redirStdout is a helper function to return the standard output from f as a
|
|
||||||
// byte slice.
|
|
||||||
func redirStdout(f func()) ([]byte, error) {
|
|
||||||
tempFile, err := ioutil.TempFile("", "ss-test")
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
fileName := tempFile.Name()
|
|
||||||
defer os.Remove(fileName) // Ignore error
|
|
||||||
|
|
||||||
origStdout := os.Stdout
|
|
||||||
os.Stdout = tempFile
|
|
||||||
f()
|
|
||||||
os.Stdout = origStdout
|
|
||||||
tempFile.Close()
|
|
||||||
|
|
||||||
return ioutil.ReadFile(fileName)
|
|
||||||
}
|
|
||||||
|
|
||||||
func initSpewTests() {
|
|
||||||
// Config states with various settings.
|
|
||||||
scsDefault := spew.NewDefaultConfig()
|
|
||||||
scsNoMethods := &spew.ConfigState{Indent: " ", DisableMethods: true}
|
|
||||||
scsNoPmethods := &spew.ConfigState{Indent: " ", DisablePointerMethods: true}
|
|
||||||
scsMaxDepth := &spew.ConfigState{Indent: " ", MaxDepth: 1}
|
|
||||||
scsContinue := &spew.ConfigState{Indent: " ", ContinueOnMethod: true}
|
|
||||||
|
|
||||||
// Variables for tests on types which implement Stringer interface with and
|
|
||||||
// without a pointer receiver.
|
|
||||||
ts := stringer("test")
|
|
||||||
tps := pstringer("test")
|
|
||||||
|
|
||||||
// depthTester is used to test max depth handling for structs, array, slices
|
|
||||||
// and maps.
|
|
||||||
type depthTester struct {
|
|
||||||
ic indirCir1
|
|
||||||
arr [1]string
|
|
||||||
slice []string
|
|
||||||
m map[string]int
|
|
||||||
}
|
|
||||||
dt := depthTester{indirCir1{nil}, [1]string{"arr"}, []string{"slice"},
|
|
||||||
map[string]int{"one": 1}}
|
|
||||||
|
|
||||||
// Variable for tests on types which implement error interface.
|
|
||||||
te := customError(10)
|
|
||||||
|
|
||||||
spewTests = []spewTest{
|
|
||||||
{scsDefault, fCSFdump, "", int8(127), "(int8) 127\n"},
|
|
||||||
{scsDefault, fCSFprint, "", int16(32767), "32767"},
|
|
||||||
{scsDefault, fCSFprintf, "%v", int32(2147483647), "2147483647"},
|
|
||||||
{scsDefault, fCSFprintln, "", int(2147483647), "2147483647\n"},
|
|
||||||
{scsDefault, fCSPrint, "", int64(9223372036854775807), "9223372036854775807"},
|
|
||||||
{scsDefault, fCSPrintln, "", uint8(255), "255\n"},
|
|
||||||
{scsDefault, fCSSdump, "", uint8(64), "(uint8) 64\n"},
|
|
||||||
{scsDefault, fCSSprint, "", complex(1, 2), "(1+2i)"},
|
|
||||||
{scsDefault, fCSSprintf, "%v", complex(float32(3), 4), "(3+4i)"},
|
|
||||||
{scsDefault, fCSSprintln, "", complex(float64(5), 6), "(5+6i)\n"},
|
|
||||||
{scsDefault, fCSErrorf, "%#v", uint16(65535), "(uint16)65535"},
|
|
||||||
{scsDefault, fCSNewFormatter, "%v", uint32(4294967295), "4294967295"},
|
|
||||||
{scsDefault, fErrorf, "%v", uint64(18446744073709551615), "18446744073709551615"},
|
|
||||||
{scsDefault, fFprint, "", float32(3.14), "3.14"},
|
|
||||||
{scsDefault, fFprintln, "", float64(6.28), "6.28\n"},
|
|
||||||
{scsDefault, fPrint, "", true, "true"},
|
|
||||||
{scsDefault, fPrintln, "", false, "false\n"},
|
|
||||||
{scsDefault, fSdump, "", complex(-10, -20), "(complex128) (-10-20i)\n"},
|
|
||||||
{scsDefault, fSprint, "", complex(-1, -2), "(-1-2i)"},
|
|
||||||
{scsDefault, fSprintf, "%v", complex(float32(-3), -4), "(-3-4i)"},
|
|
||||||
{scsDefault, fSprintln, "", complex(float64(-5), -6), "(-5-6i)\n"},
|
|
||||||
{scsNoMethods, fCSFprint, "", ts, "test"},
|
|
||||||
{scsNoMethods, fCSFprint, "", &ts, "<*>test"},
|
|
||||||
{scsNoMethods, fCSFprint, "", tps, "test"},
|
|
||||||
{scsNoMethods, fCSFprint, "", &tps, "<*>test"},
|
|
||||||
{scsNoPmethods, fCSFprint, "", ts, "stringer test"},
|
|
||||||
{scsNoPmethods, fCSFprint, "", &ts, "<*>stringer test"},
|
|
||||||
{scsNoPmethods, fCSFprint, "", tps, "test"},
|
|
||||||
{scsNoPmethods, fCSFprint, "", &tps, "<*>stringer test"},
|
|
||||||
{scsMaxDepth, fCSFprint, "", dt, "{{<max>} [<max>] [<max>] map[<max>]}"},
|
|
||||||
{scsMaxDepth, fCSFdump, "", dt, "(spew_test.depthTester) {\n" +
|
|
||||||
" ic: (spew_test.indirCir1) {\n <max depth reached>\n },\n" +
|
|
||||||
" arr: ([1]string) (len=1 cap=1) {\n <max depth reached>\n },\n" +
|
|
||||||
" slice: ([]string) (len=1 cap=1) {\n <max depth reached>\n },\n" +
|
|
||||||
" m: (map[string]int) (len=1) {\n <max depth reached>\n }\n}\n"},
|
|
||||||
{scsContinue, fCSFprint, "", ts, "(stringer test) test"},
|
|
||||||
{scsContinue, fCSFdump, "", ts, "(spew_test.stringer) " +
|
|
||||||
"(len=4) (stringer test) \"test\"\n"},
|
|
||||||
{scsContinue, fCSFprint, "", te, "(error: 10) 10"},
|
|
||||||
{scsContinue, fCSFdump, "", te, "(spew_test.customError) " +
|
|
||||||
"(error: 10) 10\n"},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestSpew executes all of the tests described by spewTests.
|
|
||||||
func TestSpew(t *testing.T) {
|
|
||||||
initSpewTests()
|
|
||||||
|
|
||||||
t.Logf("Running %d tests", len(spewTests))
|
|
||||||
for i, test := range spewTests {
|
|
||||||
buf := new(bytes.Buffer)
|
|
||||||
switch test.f {
|
|
||||||
case fCSFdump:
|
|
||||||
test.cs.Fdump(buf, test.in)
|
|
||||||
|
|
||||||
case fCSFprint:
|
|
||||||
test.cs.Fprint(buf, test.in)
|
|
||||||
|
|
||||||
case fCSFprintf:
|
|
||||||
test.cs.Fprintf(buf, test.format, test.in)
|
|
||||||
|
|
||||||
case fCSFprintln:
|
|
||||||
test.cs.Fprintln(buf, test.in)
|
|
||||||
|
|
||||||
case fCSPrint:
|
|
||||||
b, err := redirStdout(func() { test.cs.Print(test.in) })
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("%v #%d %v", test.f, i, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
buf.Write(b)
|
|
||||||
|
|
||||||
case fCSPrintln:
|
|
||||||
b, err := redirStdout(func() { test.cs.Println(test.in) })
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("%v #%d %v", test.f, i, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
buf.Write(b)
|
|
||||||
|
|
||||||
case fCSSdump:
|
|
||||||
str := test.cs.Sdump(test.in)
|
|
||||||
buf.WriteString(str)
|
|
||||||
|
|
||||||
case fCSSprint:
|
|
||||||
str := test.cs.Sprint(test.in)
|
|
||||||
buf.WriteString(str)
|
|
||||||
|
|
||||||
case fCSSprintf:
|
|
||||||
str := test.cs.Sprintf(test.format, test.in)
|
|
||||||
buf.WriteString(str)
|
|
||||||
|
|
||||||
case fCSSprintln:
|
|
||||||
str := test.cs.Sprintln(test.in)
|
|
||||||
buf.WriteString(str)
|
|
||||||
|
|
||||||
case fCSErrorf:
|
|
||||||
err := test.cs.Errorf(test.format, test.in)
|
|
||||||
buf.WriteString(err.Error())
|
|
||||||
|
|
||||||
case fCSNewFormatter:
|
|
||||||
fmt.Fprintf(buf, test.format, test.cs.NewFormatter(test.in))
|
|
||||||
|
|
||||||
case fErrorf:
|
|
||||||
err := spew.Errorf(test.format, test.in)
|
|
||||||
buf.WriteString(err.Error())
|
|
||||||
|
|
||||||
case fFprint:
|
|
||||||
spew.Fprint(buf, test.in)
|
|
||||||
|
|
||||||
case fFprintln:
|
|
||||||
spew.Fprintln(buf, test.in)
|
|
||||||
|
|
||||||
case fPrint:
|
|
||||||
b, err := redirStdout(func() { spew.Print(test.in) })
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("%v #%d %v", test.f, i, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
buf.Write(b)
|
|
||||||
|
|
||||||
case fPrintln:
|
|
||||||
b, err := redirStdout(func() { spew.Println(test.in) })
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("%v #%d %v", test.f, i, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
buf.Write(b)
|
|
||||||
|
|
||||||
case fSdump:
|
|
||||||
str := spew.Sdump(test.in)
|
|
||||||
buf.WriteString(str)
|
|
||||||
|
|
||||||
case fSprint:
|
|
||||||
str := spew.Sprint(test.in)
|
|
||||||
buf.WriteString(str)
|
|
||||||
|
|
||||||
case fSprintf:
|
|
||||||
str := spew.Sprintf(test.format, test.in)
|
|
||||||
buf.WriteString(str)
|
|
||||||
|
|
||||||
case fSprintln:
|
|
||||||
str := spew.Sprintln(test.in)
|
|
||||||
buf.WriteString(str)
|
|
||||||
|
|
||||||
default:
|
|
||||||
t.Errorf("%v #%d unrecognized function", test.f, i)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
s := buf.String()
|
|
||||||
if test.want != s {
|
|
||||||
t.Errorf("ConfigState #%d\n got: %s want: %s", i, s, test.want)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
82
Godeps/_workspace/src/github.com/davecgh/go-spew/spew/testdata/dumpcgo.go
generated
vendored
|
|
@ -1,82 +0,0 @@
|
||||||
// Copyright (c) 2013 Dave Collins <dave@davec.name>
|
|
||||||
//
|
|
||||||
// Permission to use, copy, modify, and distribute this software for any
|
|
||||||
// purpose with or without fee is hereby granted, provided that the above
|
|
||||||
// copyright notice and this permission notice appear in all copies.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
|
|
||||||
// NOTE: Due to the following build constraints, this file will only be compiled
|
|
||||||
// when both cgo is supported and "-tags testcgo" is added to the go test
|
|
||||||
// command line. This code should really only be in the dumpcgo_test.go file,
|
|
||||||
// but unfortunately Go will not allow cgo in test files, so this is a
|
|
||||||
// workaround to allow cgo types to be tested. This configuration is used
|
|
||||||
// because spew itself does not require cgo to run even though it does handle
|
|
||||||
// certain cgo types specially. Rather than forcing all clients to require cgo
|
|
||||||
// and an external C compiler just to run the tests, this scheme makes them
|
|
||||||
// optional.
|
|
||||||
// +build cgo,testcgo
|
|
||||||
|
|
||||||
package testdata
|
|
||||||
|
|
||||||
/*
|
|
||||||
#include <stdint.h>
|
|
||||||
typedef unsigned char custom_uchar_t;
|
|
||||||
|
|
||||||
char *ncp = 0;
|
|
||||||
char *cp = "test";
|
|
||||||
char ca[6] = {'t', 'e', 's', 't', '2', '\0'};
|
|
||||||
unsigned char uca[6] = {'t', 'e', 's', 't', '3', '\0'};
|
|
||||||
signed char sca[6] = {'t', 'e', 's', 't', '4', '\0'};
|
|
||||||
uint8_t ui8ta[6] = {'t', 'e', 's', 't', '5', '\0'};
|
|
||||||
custom_uchar_t tuca[6] = {'t', 'e', 's', 't', '6', '\0'};
|
|
||||||
*/
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
// GetCgoNullCharPointer returns a null char pointer via cgo. This is only
|
|
||||||
// used for tests.
|
|
||||||
func GetCgoNullCharPointer() interface{} {
|
|
||||||
return C.ncp
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetCgoCharPointer returns a char pointer via cgo. This is only used for
|
|
||||||
// tests.
|
|
||||||
func GetCgoCharPointer() interface{} {
|
|
||||||
return C.cp
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetCgoCharArray returns a char array via cgo and the array's len and cap.
|
|
||||||
// This is only used for tests.
|
|
||||||
func GetCgoCharArray() (interface{}, int, int) {
|
|
||||||
return C.ca, len(C.ca), cap(C.ca)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetCgoUnsignedCharArray returns an unsigned char array via cgo and the
|
|
||||||
// array's len and cap. This is only used for tests.
|
|
||||||
func GetCgoUnsignedCharArray() (interface{}, int, int) {
|
|
||||||
return C.uca, len(C.uca), cap(C.uca)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetCgoSignedCharArray returns a signed char array via cgo and the array's len
|
|
||||||
// and cap. This is only used for tests.
|
|
||||||
func GetCgoSignedCharArray() (interface{}, int, int) {
|
|
||||||
return C.sca, len(C.sca), cap(C.sca)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetCgoUint8tArray returns a uint8_t array via cgo and the array's len and
|
|
||||||
// cap. This is only used for tests.
|
|
||||||
func GetCgoUint8tArray() (interface{}, int, int) {
|
|
||||||
return C.ui8ta, len(C.ui8ta), cap(C.ui8ta)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetCgoTypdefedUnsignedCharArray returns a typedefed unsigned char array via
|
|
||||||
// cgo and the array's len and cap. This is only used for tests.
|
|
||||||
func GetCgoTypdefedUnsignedCharArray() (interface{}, int, int) {
|
|
||||||
return C.tuca, len(C.tuca), cap(C.tuca)
|
|
||||||
}
|
|
||||||
41
Godeps/_workspace/src/github.com/ethereum/ethash/ethash_opencl.go
generated
vendored
|
|
@ -138,7 +138,7 @@ func PrintDevices() {
|
||||||
|
|
||||||
platforms, err := cl.GetPlatforms()
|
platforms, err := cl.GetPlatforms()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Plaform error (check your OpenCL installation): %v", err)
|
fmt.Println("Plaform error (check your OpenCL installation):", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -187,8 +187,8 @@ func PrintDevices() {
|
||||||
idsFormat += ","
|
idsFormat += ","
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fmt.Printf("Found %v devices. Benchmark first GPU: geth gpubench 0\n", len(found))
|
fmt.Printf("Found %v devices. Benchmark first GPU: gexp gpubench 0\n", len(found))
|
||||||
fmt.Printf("Mine using all GPUs: geth --minegpu %v\n", idsFormat)
|
fmt.Printf("Mine using all GPUs: gexp --minegpu %v\n", idsFormat)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -197,14 +197,14 @@ func PrintDevices() {
|
||||||
func InitCL(blockNum uint64, c *OpenCLMiner) error {
|
func InitCL(blockNum uint64, c *OpenCLMiner) error {
|
||||||
platforms, err := cl.GetPlatforms()
|
platforms, err := cl.GetPlatforms()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Plaform error: %v\nCheck your OpenCL installation and then run geth gpuinfo", err)
|
return fmt.Errorf("Plaform error: %v\nCheck your OpenCL installation and then run gexp gpuinfo", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var devices []*cl.Device
|
var devices []*cl.Device
|
||||||
for _, p := range platforms {
|
for _, p := range platforms {
|
||||||
ds, err := cl.GetDevices(p, cl.DeviceTypeGPU)
|
ds, err := cl.GetDevices(p, cl.DeviceTypeGPU)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Devices error: %v\nCheck your GPU drivers and then run geth gpuinfo", err)
|
return fmt.Errorf("Devices error: %v\nCheck your GPU drivers and then run gexp gpuinfo", err)
|
||||||
}
|
}
|
||||||
for _, d := range ds {
|
for _, d := range ds {
|
||||||
devices = append(devices, d)
|
devices = append(devices, d)
|
||||||
|
|
@ -221,7 +221,7 @@ func InitCL(blockNum uint64, c *OpenCLMiner) error {
|
||||||
|
|
||||||
for _, id := range c.deviceIds {
|
for _, id := range c.deviceIds {
|
||||||
if id > len(devices)-1 {
|
if id > len(devices)-1 {
|
||||||
return fmt.Errorf("Device id not found. See available device ids with: geth gpuinfo")
|
return fmt.Errorf("Device id not found. See available device ids with: gexp gpuinfo")
|
||||||
} else {
|
} else {
|
||||||
err := initCLDevice(id, devices[id], c)
|
err := initCLDevice(id, devices[id], c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -267,13 +267,13 @@ func initCLDevice(deviceId int, device *cl.Device, c *OpenCLMiner) error {
|
||||||
|
|
||||||
context, err := cl.CreateContext([]*cl.Device{device})
|
context, err := cl.CreateContext([]*cl.Device{device})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed creating context:", err)
|
return fmt.Errorf("failed creating context: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: test running with CL_QUEUE_PROFILING_ENABLE for profiling?
|
// TODO: test running with CL_QUEUE_PROFILING_ENABLE for profiling?
|
||||||
queue, err := context.CreateCommandQueue(device, 0)
|
queue, err := context.CreateCommandQueue(device, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("command queue err:", err)
|
return fmt.Errorf("command queue err: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// See [4] section 3.2 and [3] "clBuildProgram".
|
// See [4] section 3.2 and [3] "clBuildProgram".
|
||||||
|
|
@ -287,7 +287,7 @@ func initCLDevice(deviceId int, device *cl.Device, c *OpenCLMiner) error {
|
||||||
|
|
||||||
program, err := context.CreateProgramWithSource([]string{kernelCode})
|
program, err := context.CreateProgramWithSource([]string{kernelCode})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("program err:", err)
|
return fmt.Errorf("program err: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if using AMD OpenCL impl, you can set this to debug on x86 CPU device.
|
/* if using AMD OpenCL impl, you can set this to debug on x86 CPU device.
|
||||||
|
|
@ -303,7 +303,7 @@ func initCLDevice(deviceId int, device *cl.Device, c *OpenCLMiner) error {
|
||||||
buildOpts := ""
|
buildOpts := ""
|
||||||
err = program.BuildProgram([]*cl.Device{device}, buildOpts)
|
err = program.BuildProgram([]*cl.Device{device}, buildOpts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("program build err:", err)
|
return fmt.Errorf("program build err: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var searchKernelName, hashKernelName string
|
var searchKernelName, hashKernelName string
|
||||||
|
|
@ -313,7 +313,7 @@ func initCLDevice(deviceId int, device *cl.Device, c *OpenCLMiner) error {
|
||||||
searchKernel, err := program.CreateKernel(searchKernelName)
|
searchKernel, err := program.CreateKernel(searchKernelName)
|
||||||
hashKernel, err := program.CreateKernel(hashKernelName)
|
hashKernel, err := program.CreateKernel(hashKernelName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("kernel err:", err)
|
return fmt.Errorf("kernel err: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: when this DAG size appears, patch the Go bindings
|
// TODO: when this DAG size appears, patch the Go bindings
|
||||||
|
|
@ -328,28 +328,28 @@ func initCLDevice(deviceId int, device *cl.Device, c *OpenCLMiner) error {
|
||||||
dagBuf := *(new(*cl.MemObject))
|
dagBuf := *(new(*cl.MemObject))
|
||||||
dagBuf, err = context.CreateEmptyBuffer(cl.MemReadOnly, int(c.dagSize))
|
dagBuf, err = context.CreateEmptyBuffer(cl.MemReadOnly, int(c.dagSize))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("allocating dag buf failed: ", err)
|
return fmt.Errorf("allocating dag buf failed: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// write DAG to device mem
|
// write DAG to device mem
|
||||||
dagPtr := unsafe.Pointer(c.ethash.Full.current.ptr.data)
|
dagPtr := unsafe.Pointer(c.ethash.Full.current.ptr.data)
|
||||||
_, err = queue.EnqueueWriteBuffer(dagBuf, true, 0, int(c.dagSize), dagPtr, nil)
|
_, err = queue.EnqueueWriteBuffer(dagBuf, true, 0, int(c.dagSize), dagPtr, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("writing to dag buf failed: ", err)
|
return fmt.Errorf("writing to dag buf failed: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
searchBuffers := make([]*cl.MemObject, searchBufSize)
|
searchBuffers := make([]*cl.MemObject, searchBufSize)
|
||||||
for i := 0; i < searchBufSize; i++ {
|
for i := 0; i < searchBufSize; i++ {
|
||||||
searchBuff, err := context.CreateEmptyBuffer(cl.MemWriteOnly, (1+maxSearchResults)*SIZEOF_UINT32)
|
searchBuff, err := context.CreateEmptyBuffer(cl.MemWriteOnly, (1+maxSearchResults)*SIZEOF_UINT32)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("search buffer err:", err)
|
return fmt.Errorf("search buffer err: %v", err)
|
||||||
}
|
}
|
||||||
searchBuffers[i] = searchBuff
|
searchBuffers[i] = searchBuff
|
||||||
}
|
}
|
||||||
|
|
||||||
headerBuf, err := context.CreateEmptyBuffer(cl.MemReadOnly, 32)
|
headerBuf, err := context.CreateEmptyBuffer(cl.MemReadOnly, 32)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("header buffer err:", err)
|
return fmt.Errorf("header buffer err: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unique, random nonces are crucial for mining efficieny.
|
// Unique, random nonces are crucial for mining efficieny.
|
||||||
|
|
@ -556,13 +556,13 @@ func (c *OpenCLMiner) Search(block pow.Block, stop <-chan struct{}, index int) (
|
||||||
upperNonce := uint64(binary.LittleEndian.Uint32(results[lo:hi]))
|
upperNonce := uint64(binary.LittleEndian.Uint32(results[lo:hi]))
|
||||||
checkNonce = p.startNonce + upperNonce
|
checkNonce = p.startNonce + upperNonce
|
||||||
if checkNonce != 0 {
|
if checkNonce != 0 {
|
||||||
cn := C.uint64_t(checkNonce)
|
|
||||||
ds := C.uint64_t(c.dagSize)
|
|
||||||
// We verify that the nonce is indeed a solution by
|
// We verify that the nonce is indeed a solution by
|
||||||
// executing the Ethash verification function (on the CPU).
|
// executing the Ethash verification function (on the CPU).
|
||||||
ret := C.ethash_light_compute_internal(c.ethash.Light.current.ptr, ds, hashToH256(headerHash), cn)
|
cache := c.ethash.Light.getCache(block.NumberU64())
|
||||||
|
ok, mixDigest, result := cache.compute(c.dagSize, headerHash, checkNonce)
|
||||||
|
|
||||||
// TODO: return result first
|
// TODO: return result first
|
||||||
if ret.success && h256ToHash(ret.result).Big().Cmp(target256) <= 0 {
|
if ok && result.Big().Cmp(target256) <= 0 {
|
||||||
_, err = d.queue.EnqueueUnmapMemObject(d.searchBuffers[p.bufIndex], cres, nil)
|
_, err = d.queue.EnqueueUnmapMemObject(d.searchBuffers[p.bufIndex], cres, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Error in Search clEnqueueUnmapMemObject: ", err)
|
fmt.Println("Error in Search clEnqueueUnmapMemObject: ", err)
|
||||||
|
|
@ -573,9 +573,8 @@ func (c *OpenCLMiner) Search(block pow.Block, stop <-chan struct{}, index int) (
|
||||||
fmt.Println("Error in Search WaitForEvents: ", err)
|
fmt.Println("Error in Search WaitForEvents: ", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return checkNonce, C.GoBytes(unsafe.Pointer(&ret.mix_hash), C.int(32))
|
return checkNonce, mixDigest.Bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := d.queue.EnqueueWriteBuffer(d.searchBuffers[p.bufIndex], false, 0, 4, unsafe.Pointer(&zero), nil)
|
_, err := d.queue.EnqueueWriteBuffer(d.searchBuffers[p.bufIndex], false, 0, 4, unsafe.Pointer(&zero), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Error in Search cl: EnqueueWriteBuffer", err)
|
fmt.Println("Error in Search cl: EnqueueWriteBuffer", err)
|
||||||
|
|
|
||||||
4
Godeps/_workspace/src/github.com/ethereum/ethash/ethash_opencl_kernel_go_str.go
generated
vendored
|
|
@ -407,7 +407,7 @@ hash32_t compute_hash(
|
||||||
// Compute one init hash per work item.
|
// Compute one init hash per work item.
|
||||||
hash64_t init = init_hash(g_header, nonce, isolate);
|
hash64_t init = init_hash(g_header, nonce, isolate);
|
||||||
|
|
||||||
// Threads work together in this phase in groups of 8.
|
// Threads work togexper in this phase in groups of 8.
|
||||||
uint const thread_id = gid % THREADS_PER_HASH;
|
uint const thread_id = gid % THREADS_PER_HASH;
|
||||||
uint const hash_id = (gid % GROUP_SIZE) / THREADS_PER_HASH;
|
uint const hash_id = (gid % GROUP_SIZE) / THREADS_PER_HASH;
|
||||||
|
|
||||||
|
|
@ -454,7 +454,7 @@ hash32_t compute_hash_chunks(
|
||||||
// Compute one init hash per work item.
|
// Compute one init hash per work item.
|
||||||
hash64_t init = init_hash(g_header, nonce, isolate);
|
hash64_t init = init_hash(g_header, nonce, isolate);
|
||||||
|
|
||||||
// Threads work together in this phase in groups of 8.
|
// Threads work togexper in this phase in groups of 8.
|
||||||
uint const thread_id = gid % THREADS_PER_HASH;
|
uint const thread_id = gid % THREADS_PER_HASH;
|
||||||
uint const hash_id = (gid % GROUP_SIZE) / THREADS_PER_HASH;
|
uint const hash_id = (gid % GROUP_SIZE) / THREADS_PER_HASH;
|
||||||
|
|
||||||
|
|
|
||||||
95
Godeps/_workspace/src/github.com/expanse-project/ethash/ethash.go
generated
vendored
|
|
@ -75,6 +75,7 @@ func defaultDir() string {
|
||||||
// and automatic memory management.
|
// and automatic memory management.
|
||||||
type cache struct {
|
type cache struct {
|
||||||
epoch uint64
|
epoch uint64
|
||||||
|
used time.Time
|
||||||
test bool
|
test bool
|
||||||
|
|
||||||
gen sync.Once // ensures cache is only generated once.
|
gen sync.Once // ensures cache is only generated once.
|
||||||
|
|
@ -104,14 +105,25 @@ func freeCache(cache *cache) {
|
||||||
cache.ptr = nil
|
cache.ptr = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Light implements the Verify half of the proof of work.
|
func (cache *cache) compute(dagSize uint64, hash common.Hash, nonce uint64) (ok bool, mixDigest, result common.Hash) {
|
||||||
// It uses a small in-memory cache to verify the nonces
|
ret := C.ethash_light_compute_internal(cache.ptr, C.uint64_t(dagSize), hashToH256(hash), C.uint64_t(nonce))
|
||||||
// found by Full.
|
// Make sure cache is live until after the C call.
|
||||||
|
// This is important because a GC might happen and execute
|
||||||
|
// the finalizer before the call completes.
|
||||||
|
_ = cache
|
||||||
|
return bool(ret.success), h256ToHash(ret.mix_hash), h256ToHash(ret.result)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Light implements the Verify half of the proof of work. It uses a few small
|
||||||
|
// in-memory caches to verify the nonces found by Full.
|
||||||
type Light struct {
|
type Light struct {
|
||||||
test bool // if set use a smaller cache size
|
test bool // If set, use a smaller cache size
|
||||||
mu sync.Mutex // protects current
|
|
||||||
current *cache // last cache which was generated.
|
mu sync.Mutex // Protects the per-epoch map of verification caches
|
||||||
// TODO: keep multiple caches.
|
caches map[uint64]*cache // Currently maintained verification caches
|
||||||
|
future *cache // Pre-generated cache for the estimated future DAG
|
||||||
|
|
||||||
|
NumCaches int // Maximum number of caches to keep before eviction (only init, don't modify)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify checks whether the block's nonce is valid.
|
// Verify checks whether the block's nonce is valid.
|
||||||
|
|
@ -137,29 +149,23 @@ func (l *Light) Verify(block pow.Block) bool {
|
||||||
|
|
||||||
cache := l.getCache(blockNum)
|
cache := l.getCache(blockNum)
|
||||||
dagSize := C.ethash_get_datasize(C.uint64_t(blockNum))
|
dagSize := C.ethash_get_datasize(C.uint64_t(blockNum))
|
||||||
|
|
||||||
if l.test {
|
if l.test {
|
||||||
dagSize = dagSizeForTesting
|
dagSize = dagSizeForTesting
|
||||||
}
|
}
|
||||||
// Recompute the hash using the cache.
|
// Recompute the hash using the cache.
|
||||||
hash := hashToH256(block.HashNoNonce())
|
ok, mixDigest, result := cache.compute(uint64(dagSize), block.HashNoNonce(), block.Nonce())
|
||||||
ret := C.ethash_light_compute_internal(cache.ptr, dagSize, hash, C.uint64_t(block.Nonce()))
|
if !ok {
|
||||||
if !ret.success {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// avoid mixdigest malleability as it's not included in a block's "hashNononce"
|
// avoid mixdigest malleability as it's not included in a block's "hashNononce"
|
||||||
if block.MixDigest() != h256ToHash(ret.mix_hash) {
|
if block.MixDigest() != mixDigest {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure cache is live until after the C call.
|
|
||||||
// This is important because a GC might happen and execute
|
|
||||||
// the finalizer before the call completes.
|
|
||||||
_ = cache
|
|
||||||
// The actual check.
|
// The actual check.
|
||||||
target := new(big.Int).Div(maxUint256, difficulty)
|
target := new(big.Int).Div(maxUint256, difficulty)
|
||||||
return h256ToHash(ret.result).Big().Cmp(target) <= 0
|
return result.Big().Cmp(target) <= 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func h256ToHash(in C.ethash_h256_t) common.Hash {
|
func h256ToHash(in C.ethash_h256_t) common.Hash {
|
||||||
|
|
@ -173,16 +179,49 @@ func hashToH256(in common.Hash) C.ethash_h256_t {
|
||||||
func (l *Light) getCache(blockNum uint64) *cache {
|
func (l *Light) getCache(blockNum uint64) *cache {
|
||||||
var c *cache
|
var c *cache
|
||||||
epoch := blockNum / epochLength
|
epoch := blockNum / epochLength
|
||||||
// Update or reuse the last cache.
|
|
||||||
|
// If we have a PoW for that epoch, use that
|
||||||
l.mu.Lock()
|
l.mu.Lock()
|
||||||
if l.current != nil && l.current.epoch == epoch {
|
if l.caches == nil {
|
||||||
c = l.current
|
l.caches = make(map[uint64]*cache)
|
||||||
} else {
|
|
||||||
c = &cache{epoch: epoch, test: l.test}
|
|
||||||
l.current = c
|
|
||||||
}
|
}
|
||||||
|
if l.NumCaches == 0 {
|
||||||
|
l.NumCaches = 3
|
||||||
|
}
|
||||||
|
c = l.caches[epoch]
|
||||||
|
if c == nil {
|
||||||
|
// No cached DAG, evict the oldest if the cache limit was reached
|
||||||
|
if len(l.caches) >= l.NumCaches {
|
||||||
|
var evict *cache
|
||||||
|
for _, cache := range l.caches {
|
||||||
|
if evict == nil || evict.used.After(cache.used) {
|
||||||
|
evict = cache
|
||||||
|
}
|
||||||
|
}
|
||||||
|
glog.V(logger.Debug).Infof("Evicting DAG for epoch %d in favour of epoch %d", evict.epoch, epoch)
|
||||||
|
delete(l.caches, evict.epoch)
|
||||||
|
}
|
||||||
|
// If we have the new DAG pre-generated, use that, otherwise create a new one
|
||||||
|
if l.future != nil && l.future.epoch == epoch {
|
||||||
|
glog.V(logger.Debug).Infof("Using pre-generated DAG for epoch %d", epoch)
|
||||||
|
c, l.future = l.future, nil
|
||||||
|
} else {
|
||||||
|
glog.V(logger.Debug).Infof("No pre-generated DAG available, creating new for epoch %d", epoch)
|
||||||
|
c = &cache{epoch: epoch, test: l.test}
|
||||||
|
}
|
||||||
|
l.caches[epoch] = c
|
||||||
|
|
||||||
|
// If we just used up the future cache, or need a refresh, regenerate
|
||||||
|
if l.future == nil || l.future.epoch <= epoch {
|
||||||
|
glog.V(logger.Debug).Infof("Pre-generating DAG for epoch %d", epoch+1)
|
||||||
|
l.future = &cache{epoch: epoch + 1, test: l.test}
|
||||||
|
go l.future.generate()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.used = time.Now()
|
||||||
l.mu.Unlock()
|
l.mu.Unlock()
|
||||||
// Wait for the cache to finish generating.
|
|
||||||
|
// Wait for generation finish and return the cache
|
||||||
c.generate()
|
c.generate()
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
@ -362,9 +401,13 @@ type Ethash struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates an instance of the proof of work.
|
// New creates an instance of the proof of work.
|
||||||
// A single instance of Light is shared across all instances
|
|
||||||
// created with New.
|
|
||||||
func New() *Ethash {
|
func New() *Ethash {
|
||||||
|
return &Ethash{new(Light), &Full{turbo: true}}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewShared creates an instance of the proof of work., where a single instance
|
||||||
|
// of the Light cache is shared across all instances created with NewShared.
|
||||||
|
func NewShared() *Ethash {
|
||||||
return &Ethash{sharedLight, &Full{turbo: true}}
|
return &Ethash{sharedLight, &Full{turbo: true}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
4
Godeps/_workspace/src/github.com/expanse-project/ethash/setup.py
generated
vendored
|
|
@ -39,8 +39,8 @@ setup(
|
||||||
author_email="matthew.wampler.doty@gmail.com",
|
author_email="matthew.wampler.doty@gmail.com",
|
||||||
license='GPL',
|
license='GPL',
|
||||||
version='0.1.23',
|
version='0.1.23',
|
||||||
url='https://github.com/expanse-project/ethash',
|
url='https://github.com/expanse-org/ethash',
|
||||||
download_url='https://github.com/expanse-project/ethash/tarball/v23',
|
download_url='https://github.com/expanse-org/ethash/tarball/v23',
|
||||||
description=('Python wrappers for ethash, the expanse proof of work'
|
description=('Python wrappers for ethash, the expanse proof of work'
|
||||||
'hashing function'),
|
'hashing function'),
|
||||||
ext_modules=[pyethash],
|
ext_modules=[pyethash],
|
||||||
|
|
|
||||||
2
Godeps/_workspace/src/github.com/expanse-project/ethash/src/libethash/internal.c
generated
vendored
|
|
@ -184,7 +184,7 @@ static bool ethash_hash(
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// pack hash and nonce together into first 40 bytes of s_mix
|
// pack hash and nonce togexper into first 40 bytes of s_mix
|
||||||
assert(sizeof(node) * 8 == 512);
|
assert(sizeof(node) * 8 == 512);
|
||||||
node s_mix[MIX_NODES + 1];
|
node s_mix[MIX_NODES + 1];
|
||||||
memcpy(s_mix[0].bytes, &header_hash, 32);
|
memcpy(s_mix[0].bytes, &header_hash, 32);
|
||||||
|
|
|
||||||
53
Godeps/_workspace/src/github.com/fatih/color/color.go
generated
vendored
|
|
@ -6,8 +6,8 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/mattn/go-colorable"
|
||||||
"github.com/mattn/go-isatty"
|
"github.com/mattn/go-isatty"
|
||||||
"github.com/shiena/ansicolor"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// NoColor defines if the output is colorized or not. It's dynamically set to
|
// NoColor defines if the output is colorized or not. It's dynamically set to
|
||||||
|
|
@ -53,6 +53,18 @@ const (
|
||||||
FgWhite
|
FgWhite
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Foreground Hi-Intensity text colors
|
||||||
|
const (
|
||||||
|
FgHiBlack Attribute = iota + 90
|
||||||
|
FgHiRed
|
||||||
|
FgHiGreen
|
||||||
|
FgHiYellow
|
||||||
|
FgHiBlue
|
||||||
|
FgHiMagenta
|
||||||
|
FgHiCyan
|
||||||
|
FgHiWhite
|
||||||
|
)
|
||||||
|
|
||||||
// Background text colors
|
// Background text colors
|
||||||
const (
|
const (
|
||||||
BgBlack Attribute = iota + 40
|
BgBlack Attribute = iota + 40
|
||||||
|
|
@ -65,6 +77,18 @@ const (
|
||||||
BgWhite
|
BgWhite
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Background Hi-Intensity text colors
|
||||||
|
const (
|
||||||
|
BgHiBlack Attribute = iota + 100
|
||||||
|
BgHiRed
|
||||||
|
BgHiGreen
|
||||||
|
BgHiYellow
|
||||||
|
BgHiBlue
|
||||||
|
BgHiMagenta
|
||||||
|
BgHiCyan
|
||||||
|
BgHiWhite
|
||||||
|
)
|
||||||
|
|
||||||
// New returns a newly created color object.
|
// New returns a newly created color object.
|
||||||
func New(value ...Attribute) *Color {
|
func New(value ...Attribute) *Color {
|
||||||
c := &Color{params: make([]Attribute, 0)}
|
c := &Color{params: make([]Attribute, 0)}
|
||||||
|
|
@ -123,7 +147,7 @@ func (c *Color) prepend(value Attribute) {
|
||||||
|
|
||||||
// Output defines the standard output of the print functions. By default
|
// Output defines the standard output of the print functions. By default
|
||||||
// os.Stdout is used.
|
// os.Stdout is used.
|
||||||
var Output = ansicolor.NewAnsiColorWriter(os.Stdout)
|
var Output = colorable.NewColorableStdout()
|
||||||
|
|
||||||
// Print formats using the default formats for its operands and writes to
|
// Print formats using the default formats for its operands and writes to
|
||||||
// standard output. Spaces are added between operands when neither is a
|
// standard output. Spaces are added between operands when neither is a
|
||||||
|
|
@ -259,6 +283,31 @@ func (c *Color) isNoColorSet() bool {
|
||||||
return NoColor
|
return NoColor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Equals returns a boolean value indicating whether two colors are equal.
|
||||||
|
func (c *Color) Equals(c2 *Color) bool {
|
||||||
|
if len(c.params) != len(c2.params) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, attr := range c.params {
|
||||||
|
if !c2.attrExists(attr) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Color) attrExists(a Attribute) bool {
|
||||||
|
for _, attr := range c.params {
|
||||||
|
if attr == a {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func boolPtr(v bool) *bool {
|
func boolPtr(v bool) *bool {
|
||||||
return &v
|
return &v
|
||||||
}
|
}
|
||||||
|
|
|
||||||
176
Godeps/_workspace/src/github.com/fatih/color/color_test.go
generated
vendored
|
|
@ -1,176 +0,0 @@
|
||||||
package color
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/shiena/ansicolor"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Testing colors is kinda different. First we test for given colors and their
|
|
||||||
// escaped formatted results. Next we create some visual tests to be tested.
|
|
||||||
// Each visual test includes the color name to be compared.
|
|
||||||
func TestColor(t *testing.T) {
|
|
||||||
rb := new(bytes.Buffer)
|
|
||||||
Output = rb
|
|
||||||
|
|
||||||
testColors := []struct {
|
|
||||||
text string
|
|
||||||
code Attribute
|
|
||||||
}{
|
|
||||||
{text: "black", code: FgBlack},
|
|
||||||
{text: "red", code: FgRed},
|
|
||||||
{text: "green", code: FgGreen},
|
|
||||||
{text: "yellow", code: FgYellow},
|
|
||||||
{text: "blue", code: FgBlue},
|
|
||||||
{text: "magent", code: FgMagenta},
|
|
||||||
{text: "cyan", code: FgCyan},
|
|
||||||
{text: "white", code: FgWhite},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, c := range testColors {
|
|
||||||
New(c.code).Print(c.text)
|
|
||||||
|
|
||||||
line, _ := rb.ReadString('\n')
|
|
||||||
scannedLine := fmt.Sprintf("%q", line)
|
|
||||||
colored := fmt.Sprintf("\x1b[%dm%s\x1b[0m", c.code, c.text)
|
|
||||||
escapedForm := fmt.Sprintf("%q", colored)
|
|
||||||
|
|
||||||
fmt.Printf("%s\t: %s\n", c.text, line)
|
|
||||||
|
|
||||||
if scannedLine != escapedForm {
|
|
||||||
t.Errorf("Expecting %s, got '%s'\n", escapedForm, scannedLine)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNoColor(t *testing.T) {
|
|
||||||
rb := new(bytes.Buffer)
|
|
||||||
Output = rb
|
|
||||||
|
|
||||||
testColors := []struct {
|
|
||||||
text string
|
|
||||||
code Attribute
|
|
||||||
}{
|
|
||||||
{text: "black", code: FgBlack},
|
|
||||||
{text: "red", code: FgRed},
|
|
||||||
{text: "green", code: FgGreen},
|
|
||||||
{text: "yellow", code: FgYellow},
|
|
||||||
{text: "blue", code: FgBlue},
|
|
||||||
{text: "magent", code: FgMagenta},
|
|
||||||
{text: "cyan", code: FgCyan},
|
|
||||||
{text: "white", code: FgWhite},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, c := range testColors {
|
|
||||||
p := New(c.code)
|
|
||||||
p.DisableColor()
|
|
||||||
p.Print(c.text)
|
|
||||||
|
|
||||||
line, _ := rb.ReadString('\n')
|
|
||||||
if line != c.text {
|
|
||||||
t.Errorf("Expecting %s, got '%s'\n", c.text, line)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// global check
|
|
||||||
NoColor = true
|
|
||||||
defer func() {
|
|
||||||
NoColor = false
|
|
||||||
}()
|
|
||||||
for _, c := range testColors {
|
|
||||||
p := New(c.code)
|
|
||||||
p.Print(c.text)
|
|
||||||
|
|
||||||
line, _ := rb.ReadString('\n')
|
|
||||||
if line != c.text {
|
|
||||||
t.Errorf("Expecting %s, got '%s'\n", c.text, line)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestColorVisual(t *testing.T) {
|
|
||||||
// First Visual Test
|
|
||||||
fmt.Println("")
|
|
||||||
Output = ansicolor.NewAnsiColorWriter(os.Stdout)
|
|
||||||
|
|
||||||
New(FgRed).Printf("red\t")
|
|
||||||
New(BgRed).Print(" ")
|
|
||||||
New(FgRed, Bold).Println(" red")
|
|
||||||
|
|
||||||
New(FgGreen).Printf("green\t")
|
|
||||||
New(BgGreen).Print(" ")
|
|
||||||
New(FgGreen, Bold).Println(" green")
|
|
||||||
|
|
||||||
New(FgYellow).Printf("yellow\t")
|
|
||||||
New(BgYellow).Print(" ")
|
|
||||||
New(FgYellow, Bold).Println(" yellow")
|
|
||||||
|
|
||||||
New(FgBlue).Printf("blue\t")
|
|
||||||
New(BgBlue).Print(" ")
|
|
||||||
New(FgBlue, Bold).Println(" blue")
|
|
||||||
|
|
||||||
New(FgMagenta).Printf("magenta\t")
|
|
||||||
New(BgMagenta).Print(" ")
|
|
||||||
New(FgMagenta, Bold).Println(" magenta")
|
|
||||||
|
|
||||||
New(FgCyan).Printf("cyan\t")
|
|
||||||
New(BgCyan).Print(" ")
|
|
||||||
New(FgCyan, Bold).Println(" cyan")
|
|
||||||
|
|
||||||
New(FgWhite).Printf("white\t")
|
|
||||||
New(BgWhite).Print(" ")
|
|
||||||
New(FgWhite, Bold).Println(" white")
|
|
||||||
fmt.Println("")
|
|
||||||
|
|
||||||
// Second Visual test
|
|
||||||
Black("black")
|
|
||||||
Red("red")
|
|
||||||
Green("green")
|
|
||||||
Yellow("yellow")
|
|
||||||
Blue("blue")
|
|
||||||
Magenta("magenta")
|
|
||||||
Cyan("cyan")
|
|
||||||
White("white")
|
|
||||||
|
|
||||||
// Third visual test
|
|
||||||
fmt.Println()
|
|
||||||
Set(FgBlue)
|
|
||||||
fmt.Println("is this blue?")
|
|
||||||
Unset()
|
|
||||||
|
|
||||||
Set(FgMagenta)
|
|
||||||
fmt.Println("and this magenta?")
|
|
||||||
Unset()
|
|
||||||
|
|
||||||
// Fourth Visual test
|
|
||||||
fmt.Println()
|
|
||||||
blue := New(FgBlue).PrintlnFunc()
|
|
||||||
blue("blue text with custom print func")
|
|
||||||
|
|
||||||
red := New(FgRed).PrintfFunc()
|
|
||||||
red("red text with a printf func: %d\n", 123)
|
|
||||||
|
|
||||||
put := New(FgYellow).SprintFunc()
|
|
||||||
warn := New(FgRed).SprintFunc()
|
|
||||||
|
|
||||||
fmt.Fprintf(Output, "this is a %s and this is %s.\n", put("warning"), warn("error"))
|
|
||||||
|
|
||||||
info := New(FgWhite, BgGreen).SprintFunc()
|
|
||||||
fmt.Fprintf(Output, "this %s rocks!\n", info("package"))
|
|
||||||
|
|
||||||
// Fifth Visual Test
|
|
||||||
fmt.Println()
|
|
||||||
|
|
||||||
fmt.Fprintln(Output, BlackString("black"))
|
|
||||||
fmt.Fprintln(Output, RedString("red"))
|
|
||||||
fmt.Fprintln(Output, GreenString("green"))
|
|
||||||
fmt.Fprintln(Output, YellowString("yellow"))
|
|
||||||
fmt.Fprintln(Output, BlueString("blue"))
|
|
||||||
fmt.Fprintln(Output, MagentaString("magenta"))
|
|
||||||
fmt.Fprintln(Output, CyanString("cyan"))
|
|
||||||
fmt.Fprintln(Output, WhiteString("white"))
|
|
||||||
}
|
|
||||||
1
Godeps/_workspace/src/github.com/gizak/termui/.gitignore
generated
vendored
|
|
@ -22,3 +22,4 @@ _testmain.go
|
||||||
*.exe
|
*.exe
|
||||||
*.test
|
*.test
|
||||||
*.prof
|
*.prof
|
||||||
|
.DS_Store
|
||||||
|
|
|
||||||
207
Godeps/_workspace/src/github.com/gizak/termui/README.md
generated
vendored
|
|
@ -1,23 +1,72 @@
|
||||||
# termui [](https://travis-ci.org/gizak/termui) [](https://godoc.org/github.com/gizak/termui)
|
# termui [](https://travis-ci.org/gizak/termui) [](https://godoc.org/github.com/gizak/termui)
|
||||||
|
|
||||||
## Update 23/06/2015
|
<img src="./_example/dashboard.gif" alt="demo cast under osx 10.10; Terminal.app; Menlo Regular 12pt.)" width="80%">
|
||||||
Pull requests and master branch are freezing, waiting for merging from `refactoring` branch.
|
|
||||||
|
|
||||||
## Notice
|
`termui` is a cross-platform, easy-to-compile, and fully-customizable terminal dashboard. It is inspired by [blessed-contrib](https://github.com/yaronn/blessed-contrib), but purely in Go.
|
||||||
termui comes with ABSOLUTELY NO WARRANTY, and there is a breaking change coming up (see refactoring branch) which will change the `Bufferer` interface and many others. These changes reduce calculation overhead and introduce a new drawing buffer with better capacibilities. We will step into the next stage (call it beta) after merging these changes.
|
|
||||||
|
|
||||||
## Introduction
|
Now version v2 has arrived! It brings new event system, new theme system, new `Buffer` interface and specific colour text rendering. (some docs are missing, but it will be completed soon!)
|
||||||
Go terminal dashboard. Inspired by [blessed-contrib](https://github.com/yaronn/blessed-contrib), but purely in Go.
|
|
||||||
|
|
||||||
Cross-platform, easy to compile, and fully-customizable.
|
## Installation
|
||||||
|
|
||||||
__Demo:__ (cast under osx 10.10; Terminal.app; Menlo Regular 12pt.)
|
`master` mirrors v2 branch, to install:
|
||||||
|
|
||||||
<img src="./example/dashboard.gif" alt="demo" width="600">
|
go get -u github.com/gizak/termui
|
||||||
|
|
||||||
|
For the compatible reason, you can choose to install the legacy version of `termui`:
|
||||||
|
|
||||||
|
go get gopkg.in/gizak/termui.v1
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### Layout
|
||||||
|
|
||||||
|
To use `termui`, the very first thing you may want to know is how to manage layout. `termui` offers two ways of doing this, known as absolute layout and grid layout.
|
||||||
|
|
||||||
|
__Absolute layout__
|
||||||
|
|
||||||
|
Each widget has an underlying block structure which basically is a box model. It has border, label and padding properties. A border of a widget can be chosen to hide or display (with its border label), you can pick a different front/back colour for the border as well. To display such a widget at a specific location in terminal window, you need to assign `.X`, `.Y`, `.Height`, `.Width` values for each widget before send it to `.Render`. Let's demonstrate these by a code snippet:
|
||||||
|
|
||||||
|
`````go
|
||||||
|
import ui "github.com/gizak/termui" // <- ui shortcut, optional
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
err := ui.Init()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
defer ui.Close()
|
||||||
|
|
||||||
|
p := ui.NewPar(":PRESS q TO QUIT DEMO")
|
||||||
|
p.Height = 3
|
||||||
|
p.Width = 50
|
||||||
|
p.TextFgColor = ui.ColorWhite
|
||||||
|
p.BorderLabel = "Text Box"
|
||||||
|
p.BorderFg = ui.ColorCyan
|
||||||
|
|
||||||
|
g := ui.NewGauge()
|
||||||
|
g.Percent = 50
|
||||||
|
g.Width = 50
|
||||||
|
g.Height = 3
|
||||||
|
g.Y = 11
|
||||||
|
g.BorderLabel = "Gauge"
|
||||||
|
g.BarColor = ui.ColorRed
|
||||||
|
g.BorderFg = ui.ColorWhite
|
||||||
|
g.BorderLabelFg = ui.ColorCyan
|
||||||
|
|
||||||
|
ui.Render(p, g) // feel free to call Render, it's async and non-block
|
||||||
|
|
||||||
|
// event handler...
|
||||||
|
}
|
||||||
|
`````
|
||||||
|
|
||||||
|
Note that components can be overlapped (I'd rather call this a feature...), `Render(rs ...Renderer)` renders its args from left to right (i.e. each component's weight is arising from left to right).
|
||||||
|
|
||||||
__Grid layout:__
|
__Grid layout:__
|
||||||
|
|
||||||
Expressive syntax, using [12 columns grid system](http://www.w3schools.com/bootstrap/bootstrap_grid_system.asp)
|
<img src="./_example/grid.gif" alt="grid" width="60%">
|
||||||
|
|
||||||
|
Grid layout uses [12 columns grid system](http://www.w3schools.com/bootstrap/bootstrap_grid_system.asp) with expressive syntax. To use `Grid`, all we need to do is build a widget tree consisting of `Row`s and Cols (Actually a Col is also a `Row` but with a widget endpoint attached).
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import ui "github.com/gizak/termui"
|
import ui "github.com/gizak/termui"
|
||||||
// init and create widgets...
|
// init and create widgets...
|
||||||
|
|
@ -37,111 +86,49 @@ Expressive syntax, using [12 columns grid system](http://www.w3schools.com/boots
|
||||||
|
|
||||||
ui.Render(ui.Body)
|
ui.Render(ui.Body)
|
||||||
```
|
```
|
||||||
[demo code:](https://github.com/gizak/termui/blob/master/example/grid.go)
|
|
||||||
|
|
||||||
<img src="./example/grid.gif" alt="grid" width="500">
|
### Events
|
||||||
|
|
||||||
## Installation
|
`termui` ships with a http-like event mux handling system. All events are channeled up from different sources (typing, click, windows resize, custom event) and then encoded as universal `Event` object. `Event.Path` indicates the event type and `Event.Data` stores the event data struct. Add a handler to a certain event is easy as below:
|
||||||
|
|
||||||
go get github.com/gizak/termui
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
Each component's layout is a bit like HTML block (box model), which has border and padding.
|
|
||||||
|
|
||||||
The `Border` property can be chosen to hide or display (with its border label), when it comes to display, the label takes 1 padding space (i.e. in css: `padding: 1;`, innerHeight and innerWidth therefore shrunk by 1).
|
|
||||||
|
|
||||||
`````go
|
|
||||||
import ui "github.com/gizak/termui" // <- ui shortcut, optional
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
err := ui.Init()
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
defer ui.Close()
|
|
||||||
|
|
||||||
p := ui.NewPar(":PRESS q TO QUIT DEMO")
|
|
||||||
p.Height = 3
|
|
||||||
p.Width = 50
|
|
||||||
p.TextFgColor = ui.ColorWhite
|
|
||||||
p.Border.Label = "Text Box"
|
|
||||||
p.Border.FgColor = ui.ColorCyan
|
|
||||||
|
|
||||||
g := ui.NewGauge()
|
|
||||||
g.Percent = 50
|
|
||||||
g.Width = 50
|
|
||||||
g.Height = 3
|
|
||||||
g.Y = 11
|
|
||||||
g.Border.Label = "Gauge"
|
|
||||||
g.BarColor = ui.ColorRed
|
|
||||||
g.Border.FgColor = ui.ColorWhite
|
|
||||||
g.Border.LabelFgColor = ui.ColorCyan
|
|
||||||
|
|
||||||
ui.Render(p, g)
|
|
||||||
|
|
||||||
// event handler...
|
|
||||||
}
|
|
||||||
`````
|
|
||||||
|
|
||||||
Note that components can be overlapped (I'd rather call this a feature...), `Render(rs ...Renderer)` renders its args from left to right (i.e. each component's weight is arising from left to right).
|
|
||||||
|
|
||||||
## Themes
|
|
||||||
|
|
||||||
_All_ colors in _all_ components can be changed at _any_ time, while there provides some predefined color schemes:
|
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// for now there are only two themes: default and helloworld
|
// handle key q pressing
|
||||||
termui.UseTheme("helloworld")
|
ui.Handle("/sys/kbd/q", func(ui.Event) {
|
||||||
|
// press q to quit
|
||||||
|
ui.StopLoop()
|
||||||
|
})
|
||||||
|
|
||||||
// create components...
|
ui.Handle("/sys/kbd/C-x", func(ui.Event) {
|
||||||
|
// handle Ctrl + x combination
|
||||||
|
})
|
||||||
|
|
||||||
|
ui.Handle("/sys/kbd", func(ui.Event) {
|
||||||
|
// handle all other key pressing
|
||||||
|
})
|
||||||
|
|
||||||
|
// handle a 1s timer
|
||||||
|
ui.Handle("/timer/1s", func(e ui.Event) {
|
||||||
|
t := e.Data.(ui.EvtTimer)
|
||||||
|
// t is a EvtTimer
|
||||||
|
if t.Count%2 ==0 {
|
||||||
|
// do something
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
ui.Loop() // block until StopLoop is called
|
||||||
```
|
```
|
||||||
The `default ` theme's settings depend on the user's terminal color scheme, which is saying if your terminal default font color is white and background is white, it will be like:
|
|
||||||
|
|
||||||
<img src="./example/themedefault.png" alt="default" type="image/png" width="600">
|
### Widgets
|
||||||
|
|
||||||
The `helloworld` color scheme drops in some colors!
|
Click image to see the corresponding demo codes.
|
||||||
|
|
||||||
<img src="./example/themehelloworld.png" alt="helloworld" type="image/png" width="600">
|
|
||||||
|
|
||||||
## Widgets
|
|
||||||
|
|
||||||
#### Par
|
|
||||||
|
|
||||||
[demo code](https://github.com/gizak/termui/blob/master/example/par.go)
|
|
||||||
|
|
||||||
<img src="./example/par.png" alt="par" type="image/png" width="300">
|
|
||||||
|
|
||||||
#### List
|
|
||||||
[demo code](https://github.com/gizak/termui/blob/master/example/list.go)
|
|
||||||
|
|
||||||
<img src="./example/list.png" alt="list" type="image/png" width="200">
|
|
||||||
|
|
||||||
#### Gauge
|
|
||||||
[demo code](https://github.com/gizak/termui/blob/master/example/gauge.go)
|
|
||||||
|
|
||||||
<img src="./example/gauge.png" alt="gauge" type="image/png" width="350">
|
|
||||||
|
|
||||||
#### Line Chart
|
|
||||||
[demo code](https://github.com/gizak/termui/blob/master/example/linechart.go)
|
|
||||||
|
|
||||||
<img src="./example/linechart.png" alt="linechart" type="image/png" width="450">
|
|
||||||
|
|
||||||
#### Bar Chart
|
|
||||||
[demo code](https://github.com/gizak/termui/blob/master/example/barchart.go)
|
|
||||||
|
|
||||||
<img src="./example/barchart.png" alt="barchart" type="image/png" width="150">
|
|
||||||
|
|
||||||
#### Mult-Bar / Stacked-Bar Chart
|
|
||||||
[demo code](https://github.com/gizak/termui/blob/master/example/mbarchart.go)
|
|
||||||
|
|
||||||
<img src="./example/mbarchart.png" alt="barchart" type="image/png" width="150">
|
|
||||||
|
|
||||||
#### Sparklines
|
|
||||||
[demo code](https://github.com/gizak/termui/blob/master/example/sparklines.go)
|
|
||||||
|
|
||||||
<img src="./example/sparklines.png" alt="sparklines" type="image/png" width="350">
|
|
||||||
|
|
||||||
|
[<img src="./_example/par.png" alt="par" type="image/png" width="45%">](https://github.com/gizak/termui/blob/master/_example/par.go)
|
||||||
|
[<img src="./_example/list.png" alt="list" type="image/png" width="45%">](https://github.com/gizak/termui/blob/master/_example/list.go)
|
||||||
|
[<img src="./_example/gauge.png" alt="gauge" type="image/png" width="45%">](https://github.com/gizak/termui/blob/master/_example/gauge.go)
|
||||||
|
[<img src="./_example/linechart.png" alt="linechart" type="image/png" width="45%">](https://github.com/gizak/termui/blob/master/_example/linechart.go)
|
||||||
|
[<img src="./_example/barchart.png" alt="barchart" type="image/png" width="45%">](https://github.com/gizak/termui/blob/master/_example/barchart.go)
|
||||||
|
[<img src="./_example/mbarchart.png" alt="barchart" type="image/png" width="45%">](https://github.com/gizak/termui/blob/master/_example/mbarchart.go)
|
||||||
|
[<img src="./_example/sparklines.png" alt="sparklines" type="image/png" width="45%">](https://github.com/gizak/termui/blob/master/_example/sparklines.go)
|
||||||
|
|
||||||
## GoDoc
|
## GoDoc
|
||||||
|
|
||||||
|
|
@ -150,10 +137,12 @@ The `helloworld` color scheme drops in some colors!
|
||||||
## TODO
|
## TODO
|
||||||
|
|
||||||
- [x] Grid layout
|
- [x] Grid layout
|
||||||
- [ ] Event system
|
- [x] Event system
|
||||||
- [ ] Canvas widget
|
- [x] Canvas widget
|
||||||
- [ ] Refine APIs
|
- [x] Refine APIs
|
||||||
- [ ] Focusable widgets
|
- [ ] Focusable widgets
|
||||||
|
|
||||||
|
## Changelog
|
||||||
|
|
||||||
## License
|
## License
|
||||||
This library is under the [MIT License](http://opensource.org/licenses/MIT)
|
This library is under the [MIT License](http://opensource.org/licenses/MIT)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved.
|
// Copyright 2016 Zack Guo <gizak@icloud.com>. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license that can
|
// Use of this source code is governed by a MIT license that can
|
||||||
// be found in the LICENSE file.
|
// be found in the LICENSE file.
|
||||||
|
|
||||||
|
|
@ -39,16 +39,16 @@ type BarChart struct {
|
||||||
// NewBarChart returns a new *BarChart with current theme.
|
// NewBarChart returns a new *BarChart with current theme.
|
||||||
func NewBarChart() *BarChart {
|
func NewBarChart() *BarChart {
|
||||||
bc := &BarChart{Block: *NewBlock()}
|
bc := &BarChart{Block: *NewBlock()}
|
||||||
bc.BarColor = theme.BarChartBar
|
bc.BarColor = ThemeAttr("barchart.bar.bg")
|
||||||
bc.NumColor = theme.BarChartNum
|
bc.NumColor = ThemeAttr("barchart.num.fg")
|
||||||
bc.TextColor = theme.BarChartText
|
bc.TextColor = ThemeAttr("barchart.text.fg")
|
||||||
bc.BarGap = 1
|
bc.BarGap = 1
|
||||||
bc.BarWidth = 3
|
bc.BarWidth = 3
|
||||||
return bc
|
return bc
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bc *BarChart) layout() {
|
func (bc *BarChart) layout() {
|
||||||
bc.numBar = bc.innerWidth / (bc.BarGap + bc.BarWidth)
|
bc.numBar = bc.innerArea.Dx() / (bc.BarGap + bc.BarWidth)
|
||||||
bc.labels = make([][]rune, bc.numBar)
|
bc.labels = make([][]rune, bc.numBar)
|
||||||
bc.dataNum = make([][]rune, len(bc.Data))
|
bc.dataNum = make([][]rune, len(bc.Data))
|
||||||
|
|
||||||
|
|
@ -69,7 +69,7 @@ func (bc *BarChart) layout() {
|
||||||
bc.max = bc.Data[i]
|
bc.max = bc.Data[i]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bc.scale = float64(bc.max) / float64(bc.innerHeight-1)
|
bc.scale = float64(bc.max) / float64(bc.innerArea.Dy()-1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bc *BarChart) SetMax(max int) {
|
func (bc *BarChart) SetMax(max int) {
|
||||||
|
|
@ -80,8 +80,8 @@ func (bc *BarChart) SetMax(max int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Buffer implements Bufferer interface.
|
// Buffer implements Bufferer interface.
|
||||||
func (bc *BarChart) Buffer() []Point {
|
func (bc *BarChart) Buffer() Buffer {
|
||||||
ps := bc.Block.Buffer()
|
buf := bc.Block.Buffer()
|
||||||
bc.layout()
|
bc.layout()
|
||||||
|
|
||||||
for i := 0; i < bc.numBar && i < len(bc.Data) && i < len(bc.DataLabels); i++ {
|
for i := 0; i < bc.numBar && i < len(bc.Data) && i < len(bc.DataLabels); i++ {
|
||||||
|
|
@ -90,46 +90,49 @@ func (bc *BarChart) Buffer() []Point {
|
||||||
// plot bar
|
// plot bar
|
||||||
for j := 0; j < bc.BarWidth; j++ {
|
for j := 0; j < bc.BarWidth; j++ {
|
||||||
for k := 0; k < h; k++ {
|
for k := 0; k < h; k++ {
|
||||||
p := Point{}
|
c := Cell{
|
||||||
p.Ch = ' '
|
Ch: ' ',
|
||||||
p.Bg = bc.BarColor
|
Bg: bc.BarColor,
|
||||||
if bc.BarColor == ColorDefault { // when color is default, space char treated as transparent!
|
|
||||||
p.Bg |= AttrReverse
|
|
||||||
}
|
}
|
||||||
p.X = bc.innerX + i*(bc.BarWidth+bc.BarGap) + j
|
if bc.BarColor == ColorDefault { // when color is default, space char treated as transparent!
|
||||||
p.Y = bc.innerY + bc.innerHeight - 2 - k
|
c.Bg |= AttrReverse
|
||||||
ps = append(ps, p)
|
}
|
||||||
|
x := bc.innerArea.Min.X + i*(bc.BarWidth+bc.BarGap) + j
|
||||||
|
y := bc.innerArea.Min.Y + bc.innerArea.Dy() - 2 - k
|
||||||
|
buf.Set(x, y, c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// plot text
|
// plot text
|
||||||
for j, k := 0, 0; j < len(bc.labels[i]); j++ {
|
for j, k := 0, 0; j < len(bc.labels[i]); j++ {
|
||||||
w := charWidth(bc.labels[i][j])
|
w := charWidth(bc.labels[i][j])
|
||||||
p := Point{}
|
c := Cell{
|
||||||
p.Ch = bc.labels[i][j]
|
Ch: bc.labels[i][j],
|
||||||
p.Bg = bc.BgColor
|
Bg: bc.Bg,
|
||||||
p.Fg = bc.TextColor
|
Fg: bc.TextColor,
|
||||||
p.Y = bc.innerY + bc.innerHeight - 1
|
}
|
||||||
p.X = bc.innerX + oftX + k
|
y := bc.innerArea.Min.Y + bc.innerArea.Dy() - 1
|
||||||
ps = append(ps, p)
|
x := bc.innerArea.Min.X + oftX + k
|
||||||
|
buf.Set(x, y, c)
|
||||||
k += w
|
k += w
|
||||||
}
|
}
|
||||||
// plot num
|
// plot num
|
||||||
for j := 0; j < len(bc.dataNum[i]); j++ {
|
for j := 0; j < len(bc.dataNum[i]); j++ {
|
||||||
p := Point{}
|
c := Cell{
|
||||||
p.Ch = bc.dataNum[i][j]
|
Ch: bc.dataNum[i][j],
|
||||||
p.Fg = bc.NumColor
|
Fg: bc.NumColor,
|
||||||
p.Bg = bc.BarColor
|
Bg: bc.BarColor,
|
||||||
|
}
|
||||||
if bc.BarColor == ColorDefault { // the same as above
|
if bc.BarColor == ColorDefault { // the same as above
|
||||||
p.Bg |= AttrReverse
|
c.Bg |= AttrReverse
|
||||||
}
|
}
|
||||||
if h == 0 {
|
if h == 0 {
|
||||||
p.Bg = bc.BgColor
|
c.Bg = bc.Bg
|
||||||
}
|
}
|
||||||
p.X = bc.innerX + oftX + (bc.BarWidth-len(bc.dataNum[i]))/2 + j
|
x := bc.innerArea.Min.X + oftX + (bc.BarWidth-len(bc.dataNum[i]))/2 + j
|
||||||
p.Y = bc.innerY + bc.innerHeight - 2
|
y := bc.innerArea.Min.Y + bc.innerArea.Dy() - 2
|
||||||
ps = append(ps, p)
|
buf.Set(x, y, c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return bc.Block.chopOverflow(ps)
|
return buf
|
||||||
}
|
}
|
||||||
276
Godeps/_workspace/src/github.com/gizak/termui/block.go
generated
vendored
|
|
@ -1,142 +1,240 @@
|
||||||
// Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved.
|
// Copyright 2016 Zack Guo <gizak@icloud.com>. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license that can
|
// Use of this source code is governed by a MIT license that can
|
||||||
// be found in the LICENSE file.
|
// be found in the LICENSE file.
|
||||||
|
|
||||||
package termui
|
package termui
|
||||||
|
|
||||||
|
import "image"
|
||||||
|
|
||||||
|
// Hline is a horizontal line.
|
||||||
|
type Hline struct {
|
||||||
|
X int
|
||||||
|
Y int
|
||||||
|
Len int
|
||||||
|
Fg Attribute
|
||||||
|
Bg Attribute
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vline is a vertical line.
|
||||||
|
type Vline struct {
|
||||||
|
X int
|
||||||
|
Y int
|
||||||
|
Len int
|
||||||
|
Fg Attribute
|
||||||
|
Bg Attribute
|
||||||
|
}
|
||||||
|
|
||||||
|
// Buffer draws a horizontal line.
|
||||||
|
func (l Hline) Buffer() Buffer {
|
||||||
|
if l.Len <= 0 {
|
||||||
|
return NewBuffer()
|
||||||
|
}
|
||||||
|
return NewFilledBuffer(l.X, l.Y, l.X+l.Len, l.Y+1, HORIZONTAL_LINE, l.Fg, l.Bg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Buffer draws a vertical line.
|
||||||
|
func (l Vline) Buffer() Buffer {
|
||||||
|
if l.Len <= 0 {
|
||||||
|
return NewBuffer()
|
||||||
|
}
|
||||||
|
return NewFilledBuffer(l.X, l.Y, l.X+1, l.Y+l.Len, VERTICAL_LINE, l.Fg, l.Bg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Buffer draws a box border.
|
||||||
|
func (b Block) drawBorder(buf Buffer) {
|
||||||
|
if !b.Border {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
min := b.area.Min
|
||||||
|
max := b.area.Max
|
||||||
|
|
||||||
|
x0 := min.X
|
||||||
|
y0 := min.Y
|
||||||
|
x1 := max.X - 1
|
||||||
|
y1 := max.Y - 1
|
||||||
|
|
||||||
|
// draw lines
|
||||||
|
if b.BorderTop {
|
||||||
|
buf.Merge(Hline{x0, y0, x1 - x0, b.BorderFg, b.BorderBg}.Buffer())
|
||||||
|
}
|
||||||
|
if b.BorderBottom {
|
||||||
|
buf.Merge(Hline{x0, y1, x1 - x0, b.BorderFg, b.BorderBg}.Buffer())
|
||||||
|
}
|
||||||
|
if b.BorderLeft {
|
||||||
|
buf.Merge(Vline{x0, y0, y1 - y0, b.BorderFg, b.BorderBg}.Buffer())
|
||||||
|
}
|
||||||
|
if b.BorderRight {
|
||||||
|
buf.Merge(Vline{x1, y0, y1 - y0, b.BorderFg, b.BorderBg}.Buffer())
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw corners
|
||||||
|
if b.BorderTop && b.BorderLeft && b.area.Dx() > 0 && b.area.Dy() > 0 {
|
||||||
|
buf.Set(x0, y0, Cell{TOP_LEFT, b.BorderFg, b.BorderBg})
|
||||||
|
}
|
||||||
|
if b.BorderTop && b.BorderRight && b.area.Dx() > 1 && b.area.Dy() > 0 {
|
||||||
|
buf.Set(x1, y0, Cell{TOP_RIGHT, b.BorderFg, b.BorderBg})
|
||||||
|
}
|
||||||
|
if b.BorderBottom && b.BorderLeft && b.area.Dx() > 0 && b.area.Dy() > 1 {
|
||||||
|
buf.Set(x0, y1, Cell{BOTTOM_LEFT, b.BorderFg, b.BorderBg})
|
||||||
|
}
|
||||||
|
if b.BorderBottom && b.BorderRight && b.area.Dx() > 1 && b.area.Dy() > 1 {
|
||||||
|
buf.Set(x1, y1, Cell{BOTTOM_RIGHT, b.BorderFg, b.BorderBg})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b Block) drawBorderLabel(buf Buffer) {
|
||||||
|
maxTxtW := b.area.Dx() - 2
|
||||||
|
tx := DTrimTxCls(DefaultTxBuilder.Build(b.BorderLabel, b.BorderLabelFg, b.BorderLabelBg), maxTxtW)
|
||||||
|
|
||||||
|
for i, w := 0, 0; i < len(tx); i++ {
|
||||||
|
buf.Set(b.area.Min.X+1+w, b.area.Min.Y, tx[i])
|
||||||
|
w += tx[i].Width()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Block is a base struct for all other upper level widgets,
|
// Block is a base struct for all other upper level widgets,
|
||||||
// consider it as css: display:block.
|
// consider it as css: display:block.
|
||||||
// Normally you do not need to create it manually.
|
// Normally you do not need to create it manually.
|
||||||
type Block struct {
|
type Block struct {
|
||||||
|
area image.Rectangle
|
||||||
|
innerArea image.Rectangle
|
||||||
X int
|
X int
|
||||||
Y int
|
Y int
|
||||||
Border labeledBorder
|
Border bool
|
||||||
IsDisplay bool
|
BorderFg Attribute
|
||||||
HasBorder bool
|
BorderBg Attribute
|
||||||
BgColor Attribute
|
BorderLeft bool
|
||||||
|
BorderRight bool
|
||||||
|
BorderTop bool
|
||||||
|
BorderBottom bool
|
||||||
|
BorderLabel string
|
||||||
|
BorderLabelFg Attribute
|
||||||
|
BorderLabelBg Attribute
|
||||||
|
Display bool
|
||||||
|
Bg Attribute
|
||||||
Width int
|
Width int
|
||||||
Height int
|
Height int
|
||||||
innerWidth int
|
|
||||||
innerHeight int
|
|
||||||
innerX int
|
|
||||||
innerY int
|
|
||||||
PaddingTop int
|
PaddingTop int
|
||||||
PaddingBottom int
|
PaddingBottom int
|
||||||
PaddingLeft int
|
PaddingLeft int
|
||||||
PaddingRight int
|
PaddingRight int
|
||||||
|
id string
|
||||||
|
Float Align
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewBlock returns a *Block which inherits styles from current theme.
|
// NewBlock returns a *Block which inherits styles from current theme.
|
||||||
func NewBlock() *Block {
|
func NewBlock() *Block {
|
||||||
d := Block{}
|
b := Block{}
|
||||||
d.IsDisplay = true
|
b.Display = true
|
||||||
d.HasBorder = theme.HasBorder
|
b.Border = true
|
||||||
d.Border.BgColor = theme.BorderBg
|
b.BorderLeft = true
|
||||||
d.Border.FgColor = theme.BorderFg
|
b.BorderRight = true
|
||||||
d.Border.LabelBgColor = theme.BorderLabelTextBg
|
b.BorderTop = true
|
||||||
d.Border.LabelFgColor = theme.BorderLabelTextFg
|
b.BorderBottom = true
|
||||||
d.BgColor = theme.BlockBg
|
b.BorderBg = ThemeAttr("border.bg")
|
||||||
d.Width = 2
|
b.BorderFg = ThemeAttr("border.fg")
|
||||||
d.Height = 2
|
b.BorderLabelBg = ThemeAttr("label.bg")
|
||||||
return &d
|
b.BorderLabelFg = ThemeAttr("label.fg")
|
||||||
|
b.Bg = ThemeAttr("block.bg")
|
||||||
|
b.Width = 2
|
||||||
|
b.Height = 2
|
||||||
|
b.id = GenId()
|
||||||
|
b.Float = AlignNone
|
||||||
|
return &b
|
||||||
}
|
}
|
||||||
|
|
||||||
// compute box model
|
func (b Block) Id() string {
|
||||||
func (d *Block) align() {
|
return b.id
|
||||||
d.innerWidth = d.Width - d.PaddingLeft - d.PaddingRight
|
}
|
||||||
d.innerHeight = d.Height - d.PaddingTop - d.PaddingBottom
|
|
||||||
d.innerX = d.X + d.PaddingLeft
|
|
||||||
d.innerY = d.Y + d.PaddingTop
|
|
||||||
|
|
||||||
if d.HasBorder {
|
// Align computes box model
|
||||||
d.innerHeight -= 2
|
func (b *Block) Align() {
|
||||||
d.innerWidth -= 2
|
// outer
|
||||||
d.Border.X = d.X
|
b.area.Min.X = 0
|
||||||
d.Border.Y = d.Y
|
b.area.Min.Y = 0
|
||||||
d.Border.Width = d.Width
|
b.area.Max.X = b.Width
|
||||||
d.Border.Height = d.Height
|
b.area.Max.Y = b.Height
|
||||||
d.innerX++
|
|
||||||
d.innerY++
|
|
||||||
}
|
|
||||||
|
|
||||||
if d.innerHeight < 0 {
|
// float
|
||||||
d.innerHeight = 0
|
b.area = AlignArea(TermRect(), b.area, b.Float)
|
||||||
}
|
b.area = MoveArea(b.area, b.X, b.Y)
|
||||||
if d.innerWidth < 0 {
|
|
||||||
d.innerWidth = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// inner
|
||||||
|
b.innerArea.Min.X = b.area.Min.X + b.PaddingLeft
|
||||||
|
b.innerArea.Min.Y = b.area.Min.Y + b.PaddingTop
|
||||||
|
b.innerArea.Max.X = b.area.Max.X - b.PaddingRight
|
||||||
|
b.innerArea.Max.Y = b.area.Max.Y - b.PaddingBottom
|
||||||
|
|
||||||
|
if b.Border {
|
||||||
|
if b.BorderLeft {
|
||||||
|
b.innerArea.Min.X++
|
||||||
|
}
|
||||||
|
if b.BorderRight {
|
||||||
|
b.innerArea.Max.X--
|
||||||
|
}
|
||||||
|
if b.BorderTop {
|
||||||
|
b.innerArea.Min.Y++
|
||||||
|
}
|
||||||
|
if b.BorderBottom {
|
||||||
|
b.innerArea.Max.Y--
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// InnerBounds returns the internal bounds of the block after aligning and
|
// InnerBounds returns the internal bounds of the block after aligning and
|
||||||
// calculating the padding and border, if any.
|
// calculating the padding and border, if any.
|
||||||
func (d *Block) InnerBounds() (x, y, width, height int) {
|
func (b *Block) InnerBounds() image.Rectangle {
|
||||||
d.align()
|
b.Align()
|
||||||
return d.innerX, d.innerY, d.innerWidth, d.innerHeight
|
return b.innerArea
|
||||||
}
|
}
|
||||||
|
|
||||||
// Buffer implements Bufferer interface.
|
// Buffer implements Bufferer interface.
|
||||||
// Draw background and border (if any).
|
// Draw background and border (if any).
|
||||||
func (d *Block) Buffer() []Point {
|
func (b *Block) Buffer() Buffer {
|
||||||
d.align()
|
b.Align()
|
||||||
|
|
||||||
ps := []Point{}
|
buf := NewBuffer()
|
||||||
if !d.IsDisplay {
|
buf.SetArea(b.area)
|
||||||
return ps
|
buf.Fill(' ', ColorDefault, b.Bg)
|
||||||
}
|
|
||||||
|
|
||||||
if d.HasBorder {
|
b.drawBorder(buf)
|
||||||
ps = d.Border.Buffer()
|
b.drawBorderLabel(buf)
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < d.innerWidth; i++ {
|
return buf
|
||||||
for j := 0; j < d.innerHeight; j++ {
|
|
||||||
p := Point{}
|
|
||||||
p.X = d.X + 1 + i
|
|
||||||
p.Y = d.Y + 1 + j
|
|
||||||
p.Ch = ' '
|
|
||||||
p.Bg = d.BgColor
|
|
||||||
ps = append(ps, p)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ps
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetHeight implements GridBufferer.
|
// GetHeight implements GridBufferer.
|
||||||
// It returns current height of the block.
|
// It returns current height of the block.
|
||||||
func (d Block) GetHeight() int {
|
func (b Block) GetHeight() int {
|
||||||
return d.Height
|
return b.Height
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetX implements GridBufferer interface, which sets block's x position.
|
// SetX implements GridBufferer interface, which sets block's x position.
|
||||||
func (d *Block) SetX(x int) {
|
func (b *Block) SetX(x int) {
|
||||||
d.X = x
|
b.X = x
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetY implements GridBufferer interface, it sets y position for block.
|
// SetY implements GridBufferer interface, it sets y position for block.
|
||||||
func (d *Block) SetY(y int) {
|
func (b *Block) SetY(y int) {
|
||||||
d.Y = y
|
b.Y = y
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetWidth implements GridBuffer interface, it sets block's width.
|
// SetWidth implements GridBuffer interface, it sets block's width.
|
||||||
func (d *Block) SetWidth(w int) {
|
func (b *Block) SetWidth(w int) {
|
||||||
d.Width = w
|
b.Width = w
|
||||||
}
|
}
|
||||||
|
|
||||||
// chop the overflow parts
|
func (b Block) InnerWidth() int {
|
||||||
func (d *Block) chopOverflow(ps []Point) []Point {
|
return b.innerArea.Dx()
|
||||||
nps := make([]Point, 0, len(ps))
|
|
||||||
x := d.X
|
|
||||||
y := d.Y
|
|
||||||
w := d.Width
|
|
||||||
h := d.Height
|
|
||||||
for _, v := range ps {
|
|
||||||
if v.X >= x &&
|
|
||||||
v.X < x+w &&
|
|
||||||
v.Y >= y &&
|
|
||||||
v.Y < y+h {
|
|
||||||
nps = append(nps, v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nps
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b Block) InnerHeight() int {
|
||||||
|
return b.innerArea.Dy()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b Block) InnerX() int {
|
||||||
|
return b.innerArea.Min.X
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b Block) InnerY() int { return b.innerArea.Min.Y }
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved.
|
// Copyright 2016 Zack Guo <gizak@icloud.com>. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license that can
|
// Use of this source code is governed by a MIT license that can
|
||||||
// be found in the LICENSE file.
|
// be found in the LICENSE file.
|
||||||
|
|
||||||
|
|
@ -12,3 +12,9 @@ const HORIZONTAL_LINE = '─'
|
||||||
const TOP_LEFT = '┌'
|
const TOP_LEFT = '┌'
|
||||||
const BOTTOM_RIGHT = '┘'
|
const BOTTOM_RIGHT = '┘'
|
||||||
const BOTTOM_LEFT = '└'
|
const BOTTOM_LEFT = '└'
|
||||||
|
const VERTICAL_LEFT = '┤'
|
||||||
|
const VERTICAL_RIGHT = '├'
|
||||||
|
const HORIZONTAL_DOWN = '┬'
|
||||||
|
const HORIZONTAL_UP = '┴'
|
||||||
|
const QUOTA_LEFT = '«'
|
||||||
|
const QUOTA_RIGHT = '»'
|
||||||
46
Godeps/_workspace/src/github.com/gizak/termui/block_test.go
generated
vendored
|
|
@ -1,46 +0,0 @@
|
||||||
package termui
|
|
||||||
|
|
||||||
import "testing"
|
|
||||||
|
|
||||||
func TestBlock_InnerBounds(t *testing.T) {
|
|
||||||
b := NewBlock()
|
|
||||||
b.X = 10
|
|
||||||
b.Y = 11
|
|
||||||
b.Width = 12
|
|
||||||
b.Height = 13
|
|
||||||
|
|
||||||
assert := func(name string, x, y, w, h int) {
|
|
||||||
t.Log(name)
|
|
||||||
cx, cy, cw, ch := b.InnerBounds()
|
|
||||||
if cx != x {
|
|
||||||
t.Errorf("expected x to be %d but got %d", x, cx)
|
|
||||||
}
|
|
||||||
if cy != y {
|
|
||||||
t.Errorf("expected y to be %d but got %d", y, cy)
|
|
||||||
}
|
|
||||||
if cw != w {
|
|
||||||
t.Errorf("expected width to be %d but got %d", w, cw)
|
|
||||||
}
|
|
||||||
if ch != h {
|
|
||||||
t.Errorf("expected height to be %d but got %d", h, ch)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
b.HasBorder = false
|
|
||||||
assert("no border, no padding", 10, 11, 12, 13)
|
|
||||||
|
|
||||||
b.HasBorder = true
|
|
||||||
assert("border, no padding", 11, 12, 10, 11)
|
|
||||||
|
|
||||||
b.PaddingBottom = 2
|
|
||||||
assert("border, 2b padding", 11, 12, 10, 9)
|
|
||||||
|
|
||||||
b.PaddingTop = 3
|
|
||||||
assert("border, 2b 3t padding", 11, 15, 10, 6)
|
|
||||||
|
|
||||||
b.PaddingLeft = 4
|
|
||||||
assert("border, 2b 3t 4l padding", 15, 15, 6, 6)
|
|
||||||
|
|
||||||
b.PaddingRight = 5
|
|
||||||
assert("border, 2b 3t 4l 5r padding", 15, 15, 1, 6)
|
|
||||||
}
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved.
|
// Copyright 2016 Zack Guo <gizak@icloud.com>. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license that can
|
// Use of this source code is governed by a MIT license that can
|
||||||
// be found in the LICENSE file.
|
// be found in the LICENSE file.
|
||||||
|
|
||||||
117
Godeps/_workspace/src/github.com/gizak/termui/box.go
generated
vendored
|
|
@ -1,117 +0,0 @@
|
||||||
// Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved.
|
|
||||||
// Use of this source code is governed by a MIT license that can
|
|
||||||
// be found in the LICENSE file.
|
|
||||||
|
|
||||||
package termui
|
|
||||||
|
|
||||||
type border struct {
|
|
||||||
X int
|
|
||||||
Y int
|
|
||||||
Width int
|
|
||||||
Height int
|
|
||||||
FgColor Attribute
|
|
||||||
BgColor Attribute
|
|
||||||
}
|
|
||||||
|
|
||||||
type hline struct {
|
|
||||||
X int
|
|
||||||
Y int
|
|
||||||
Length int
|
|
||||||
FgColor Attribute
|
|
||||||
BgColor Attribute
|
|
||||||
}
|
|
||||||
|
|
||||||
type vline struct {
|
|
||||||
X int
|
|
||||||
Y int
|
|
||||||
Length int
|
|
||||||
FgColor Attribute
|
|
||||||
BgColor Attribute
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw a horizontal line.
|
|
||||||
func (l hline) Buffer() []Point {
|
|
||||||
pts := make([]Point, l.Length)
|
|
||||||
for i := 0; i < l.Length; i++ {
|
|
||||||
pts[i].X = l.X + i
|
|
||||||
pts[i].Y = l.Y
|
|
||||||
pts[i].Ch = HORIZONTAL_LINE
|
|
||||||
pts[i].Bg = l.BgColor
|
|
||||||
pts[i].Fg = l.FgColor
|
|
||||||
}
|
|
||||||
return pts
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw a vertical line.
|
|
||||||
func (l vline) Buffer() []Point {
|
|
||||||
pts := make([]Point, l.Length)
|
|
||||||
for i := 0; i < l.Length; i++ {
|
|
||||||
pts[i].X = l.X
|
|
||||||
pts[i].Y = l.Y + i
|
|
||||||
pts[i].Ch = VERTICAL_LINE
|
|
||||||
pts[i].Bg = l.BgColor
|
|
||||||
pts[i].Fg = l.FgColor
|
|
||||||
}
|
|
||||||
return pts
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw a box border.
|
|
||||||
func (b border) Buffer() []Point {
|
|
||||||
if b.Width < 2 || b.Height < 2 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
pts := make([]Point, 2*b.Width+2*b.Height-4)
|
|
||||||
|
|
||||||
pts[0].X = b.X
|
|
||||||
pts[0].Y = b.Y
|
|
||||||
pts[0].Fg = b.FgColor
|
|
||||||
pts[0].Bg = b.BgColor
|
|
||||||
pts[0].Ch = TOP_LEFT
|
|
||||||
|
|
||||||
pts[1].X = b.X + b.Width - 1
|
|
||||||
pts[1].Y = b.Y
|
|
||||||
pts[1].Fg = b.FgColor
|
|
||||||
pts[1].Bg = b.BgColor
|
|
||||||
pts[1].Ch = TOP_RIGHT
|
|
||||||
|
|
||||||
pts[2].X = b.X
|
|
||||||
pts[2].Y = b.Y + b.Height - 1
|
|
||||||
pts[2].Fg = b.FgColor
|
|
||||||
pts[2].Bg = b.BgColor
|
|
||||||
pts[2].Ch = BOTTOM_LEFT
|
|
||||||
|
|
||||||
pts[3].X = b.X + b.Width - 1
|
|
||||||
pts[3].Y = b.Y + b.Height - 1
|
|
||||||
pts[3].Fg = b.FgColor
|
|
||||||
pts[3].Bg = b.BgColor
|
|
||||||
pts[3].Ch = BOTTOM_RIGHT
|
|
||||||
|
|
||||||
copy(pts[4:], (hline{b.X + 1, b.Y, b.Width - 2, b.FgColor, b.BgColor}).Buffer())
|
|
||||||
copy(pts[4+b.Width-2:], (hline{b.X + 1, b.Y + b.Height - 1, b.Width - 2, b.FgColor, b.BgColor}).Buffer())
|
|
||||||
copy(pts[4+2*b.Width-4:], (vline{b.X, b.Y + 1, b.Height - 2, b.FgColor, b.BgColor}).Buffer())
|
|
||||||
copy(pts[4+2*b.Width-4+b.Height-2:], (vline{b.X + b.Width - 1, b.Y + 1, b.Height - 2, b.FgColor, b.BgColor}).Buffer())
|
|
||||||
|
|
||||||
return pts
|
|
||||||
}
|
|
||||||
|
|
||||||
type labeledBorder struct {
|
|
||||||
border
|
|
||||||
Label string
|
|
||||||
LabelFgColor Attribute
|
|
||||||
LabelBgColor Attribute
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw a box border with label.
|
|
||||||
func (lb labeledBorder) Buffer() []Point {
|
|
||||||
ps := lb.border.Buffer()
|
|
||||||
maxTxtW := lb.Width - 2
|
|
||||||
rs := trimStr2Runes(lb.Label, maxTxtW)
|
|
||||||
|
|
||||||
for i, j, w := 0, 0, 0; i < len(rs); i++ {
|
|
||||||
w = charWidth(rs[i])
|
|
||||||
ps = append(ps, newPointWithAttrs(rs[i], lb.X+1+j, lb.Y, lb.LabelFgColor, lb.LabelBgColor))
|
|
||||||
j += w
|
|
||||||
}
|
|
||||||
|
|
||||||
return ps
|
|
||||||
}
|
|
||||||
106
Godeps/_workspace/src/github.com/gizak/termui/buffer.go
generated
vendored
Normal file
|
|
@ -0,0 +1,106 @@
|
||||||
|
// Copyright 2016 Zack Guo <gizak@icloud.com>. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT license that can
|
||||||
|
// be found in the LICENSE file.
|
||||||
|
|
||||||
|
package termui
|
||||||
|
|
||||||
|
import "image"
|
||||||
|
|
||||||
|
// Cell is a rune with assigned Fg and Bg
|
||||||
|
type Cell struct {
|
||||||
|
Ch rune
|
||||||
|
Fg Attribute
|
||||||
|
Bg Attribute
|
||||||
|
}
|
||||||
|
|
||||||
|
// Buffer is a renderable rectangle cell data container.
|
||||||
|
type Buffer struct {
|
||||||
|
Area image.Rectangle // selected drawing area
|
||||||
|
CellMap map[image.Point]Cell
|
||||||
|
}
|
||||||
|
|
||||||
|
// At returns the cell at (x,y).
|
||||||
|
func (b Buffer) At(x, y int) Cell {
|
||||||
|
return b.CellMap[image.Pt(x, y)]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set assigns a char to (x,y)
|
||||||
|
func (b Buffer) Set(x, y int, c Cell) {
|
||||||
|
b.CellMap[image.Pt(x, y)] = c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bounds returns the domain for which At can return non-zero color.
|
||||||
|
func (b Buffer) Bounds() image.Rectangle {
|
||||||
|
x0, y0, x1, y1 := 0, 0, 0, 0
|
||||||
|
for p := range b.CellMap {
|
||||||
|
if p.X > x1 {
|
||||||
|
x1 = p.X
|
||||||
|
}
|
||||||
|
if p.X < x0 {
|
||||||
|
x0 = p.X
|
||||||
|
}
|
||||||
|
if p.Y > y1 {
|
||||||
|
y1 = p.Y
|
||||||
|
}
|
||||||
|
if p.Y < y0 {
|
||||||
|
y0 = p.Y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return image.Rect(x0, y0, x1, y1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetArea assigns a new rect area to Buffer b.
|
||||||
|
func (b *Buffer) SetArea(r image.Rectangle) {
|
||||||
|
b.Area.Max = r.Max
|
||||||
|
b.Area.Min = r.Min
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sync sets drawing area to the buffer's bound
|
||||||
|
func (b Buffer) Sync() {
|
||||||
|
b.SetArea(b.Bounds())
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewCell returns a new cell
|
||||||
|
func NewCell(ch rune, fg, bg Attribute) Cell {
|
||||||
|
return Cell{ch, fg, bg}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Merge merges bs Buffers onto b
|
||||||
|
func (b *Buffer) Merge(bs ...Buffer) {
|
||||||
|
for _, buf := range bs {
|
||||||
|
for p, v := range buf.CellMap {
|
||||||
|
b.Set(p.X, p.Y, v)
|
||||||
|
}
|
||||||
|
b.SetArea(b.Area.Union(buf.Area))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewBuffer returns a new Buffer
|
||||||
|
func NewBuffer() Buffer {
|
||||||
|
return Buffer{
|
||||||
|
CellMap: make(map[image.Point]Cell),
|
||||||
|
Area: image.Rectangle{}}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill fills the Buffer b with ch,fg and bg.
|
||||||
|
func (b Buffer) Fill(ch rune, fg, bg Attribute) {
|
||||||
|
for x := b.Area.Min.X; x < b.Area.Max.X; x++ {
|
||||||
|
for y := b.Area.Min.Y; y < b.Area.Max.Y; y++ {
|
||||||
|
b.Set(x, y, Cell{ch, fg, bg})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewFilledBuffer returns a new Buffer filled with ch, fb and bg.
|
||||||
|
func NewFilledBuffer(x0, y0, x1, y1 int, ch rune, fg, bg Attribute) Buffer {
|
||||||
|
buf := NewBuffer()
|
||||||
|
buf.Area.Min = image.Pt(x0, y0)
|
||||||
|
buf.Area.Max = image.Pt(x1, y1)
|
||||||
|
|
||||||
|
for x := buf.Area.Min.X; x < buf.Area.Max.X; x++ {
|
||||||
|
for y := buf.Area.Min.Y; y < buf.Area.Max.Y; y++ {
|
||||||
|
buf.Set(x, y, Cell{ch, fg, bg})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buf
|
||||||
|
}
|
||||||
12
Godeps/_workspace/src/github.com/gizak/termui/canvas.go
generated
vendored
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved.
|
// Copyright 2016 Zack Guo <gizak@icloud.com>. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license that can
|
// Use of this source code is governed by a MIT license that can
|
||||||
// be found in the LICENSE file.
|
// be found in the LICENSE file.
|
||||||
|
|
||||||
|
|
@ -63,12 +63,10 @@ func (c Canvas) Unset(x, y int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Buffer returns un-styled points
|
// Buffer returns un-styled points
|
||||||
func (c Canvas) Buffer() []Point {
|
func (c Canvas) Buffer() Buffer {
|
||||||
ps := make([]Point, len(c))
|
buf := NewBuffer()
|
||||||
i := 0
|
|
||||||
for k, v := range c {
|
for k, v := range c {
|
||||||
ps[i] = newPoint(v+brailleBase, k[0], k[1])
|
buf.Set(k[0], k[1], Cell{Ch: v + brailleBase})
|
||||||
i++
|
|
||||||
}
|
}
|
||||||
return ps
|
return buf
|
||||||
}
|
}
|
||||||
|
|
|
||||||
55
Godeps/_workspace/src/github.com/gizak/termui/canvas_test.go
generated
vendored
|
|
@ -1,55 +0,0 @@
|
||||||
package termui
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestCanvasSet(t *testing.T) {
|
|
||||||
c := NewCanvas()
|
|
||||||
c.Set(0, 0)
|
|
||||||
c.Set(0, 1)
|
|
||||||
c.Set(0, 2)
|
|
||||||
c.Set(0, 3)
|
|
||||||
c.Set(1, 3)
|
|
||||||
c.Set(2, 3)
|
|
||||||
c.Set(3, 3)
|
|
||||||
c.Set(4, 3)
|
|
||||||
c.Set(5, 3)
|
|
||||||
spew.Dump(c)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCanvasUnset(t *testing.T) {
|
|
||||||
c := NewCanvas()
|
|
||||||
c.Set(0, 0)
|
|
||||||
c.Set(0, 1)
|
|
||||||
c.Set(0, 2)
|
|
||||||
c.Unset(0, 2)
|
|
||||||
spew.Dump(c)
|
|
||||||
c.Unset(0, 3)
|
|
||||||
spew.Dump(c)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCanvasBuffer(t *testing.T) {
|
|
||||||
c := NewCanvas()
|
|
||||||
c.Set(0, 0)
|
|
||||||
c.Set(0, 1)
|
|
||||||
c.Set(0, 2)
|
|
||||||
c.Set(0, 3)
|
|
||||||
c.Set(1, 3)
|
|
||||||
c.Set(2, 3)
|
|
||||||
c.Set(3, 3)
|
|
||||||
c.Set(4, 3)
|
|
||||||
c.Set(5, 3)
|
|
||||||
c.Set(6, 3)
|
|
||||||
c.Set(7, 2)
|
|
||||||
c.Set(8, 1)
|
|
||||||
c.Set(9, 0)
|
|
||||||
bufs := c.Buffer()
|
|
||||||
rs := make([]rune, len(bufs))
|
|
||||||
for i, v := range bufs {
|
|
||||||
rs[i] = v.Ch
|
|
||||||
}
|
|
||||||
spew.Dump(string(rs))
|
|
||||||
}
|
|
||||||
26
Godeps/_workspace/src/github.com/gizak/termui/config
generated
vendored
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
#!/usr/bin/env perl6
|
||||||
|
|
||||||
|
use v6;
|
||||||
|
|
||||||
|
my $copyright = '// Copyright 2016 Zack Guo <gizak@icloud.com>. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT license that can
|
||||||
|
// be found in the LICENSE file.
|
||||||
|
|
||||||
|
';
|
||||||
|
|
||||||
|
sub MAIN('update-docstr', Str $srcp) {
|
||||||
|
if $srcp.IO.f {
|
||||||
|
$_ = $srcp.IO.slurp;
|
||||||
|
if m/^ \/\/\s Copyright .+? \n\n/ {
|
||||||
|
unless ~$/ eq $copyright {
|
||||||
|
s/^ \/\/\s Copyright .+? \n\n /$copyright/;
|
||||||
|
spurt $srcp, $_;
|
||||||
|
say "[updated] doc string for:"~$srcp;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
say "[added] doc string for "~$srcp~" (no match found)";
|
||||||
|
$_ = $copyright ~ $_;
|
||||||
|
spurt $srcp, $_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
117
Godeps/_workspace/src/github.com/gizak/termui/debug/debuger.go
generated
vendored
Normal file
|
|
@ -0,0 +1,117 @@
|
||||||
|
// Copyright 2016 Zack Guo <gizak@icloud.com>. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT license that can
|
||||||
|
// be found in the LICENSE file.
|
||||||
|
|
||||||
|
package debug
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"golang.org/x/net/websocket"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Server struct {
|
||||||
|
Port string
|
||||||
|
Addr string
|
||||||
|
Path string
|
||||||
|
Msg chan string
|
||||||
|
chs []chan string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Client struct {
|
||||||
|
Port string
|
||||||
|
Addr string
|
||||||
|
Path string
|
||||||
|
ws *websocket.Conn
|
||||||
|
}
|
||||||
|
|
||||||
|
var defaultPort = ":8080"
|
||||||
|
|
||||||
|
func NewServer() *Server {
|
||||||
|
return &Server{
|
||||||
|
Port: defaultPort,
|
||||||
|
Addr: "localhost",
|
||||||
|
Path: "/echo",
|
||||||
|
Msg: make(chan string),
|
||||||
|
chs: make([]chan string, 0),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewClient() Client {
|
||||||
|
return Client{
|
||||||
|
Port: defaultPort,
|
||||||
|
Addr: "localhost",
|
||||||
|
Path: "/echo",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c Client) ConnectAndListen() error {
|
||||||
|
ws, err := websocket.Dial("ws://"+c.Addr+c.Port+c.Path, "", "http://"+c.Addr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer ws.Close()
|
||||||
|
|
||||||
|
var m string
|
||||||
|
for {
|
||||||
|
err := websocket.Message.Receive(ws, &m)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Print(err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Print(m)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) ListenAndServe() error {
|
||||||
|
http.Handle(s.Path, websocket.Handler(func(ws *websocket.Conn) {
|
||||||
|
defer ws.Close()
|
||||||
|
|
||||||
|
mc := make(chan string)
|
||||||
|
s.chs = append(s.chs, mc)
|
||||||
|
|
||||||
|
for m := range mc {
|
||||||
|
websocket.Message.Send(ws, m)
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
for msg := range s.Msg {
|
||||||
|
for _, c := range s.chs {
|
||||||
|
go func(a chan string) {
|
||||||
|
a <- msg
|
||||||
|
}(c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
return http.ListenAndServe(s.Port, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) Log(msg string) {
|
||||||
|
go func() { s.Msg <- msg }()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) Logf(format string, a ...interface{}) {
|
||||||
|
s.Log(fmt.Sprintf(format, a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
var DefaultServer = NewServer()
|
||||||
|
var DefaultClient = NewClient()
|
||||||
|
|
||||||
|
func ListenAndServe() error {
|
||||||
|
return DefaultServer.ListenAndServe()
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConnectAndListen() error {
|
||||||
|
return DefaultClient.ConnectAndListen()
|
||||||
|
}
|
||||||
|
|
||||||
|
func Log(msg string) {
|
||||||
|
DefaultServer.Log(msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Logf(format string, a ...interface{}) {
|
||||||
|
DefaultServer.Logf(format, a...)
|
||||||
|
}
|
||||||
2
Godeps/_workspace/src/github.com/gizak/termui/doc.go
generated
vendored
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved.
|
// Copyright 2016 Zack Guo <gizak@icloud.com>. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license that can
|
// Use of this source code is governed by a MIT license that can
|
||||||
// be found in the LICENSE file.
|
// be found in the LICENSE file.
|
||||||
|
|
||||||
|
|
|
||||||
493
Godeps/_workspace/src/github.com/gizak/termui/events.go
generated
vendored
|
|
@ -1,219 +1,316 @@
|
||||||
// Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved.
|
// Copyright 2016 Zack Guo <gizak@icloud.com>. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license that can
|
// Use of this source code is governed by a MIT license that can
|
||||||
// be found in the LICENSE file.
|
// be found in the LICENSE file.
|
||||||
//
|
|
||||||
// Portions of this file uses [termbox-go](https://github.com/nsf/termbox-go/blob/54b74d087b7c397c402d0e3b66d2ccb6eaf5c2b4/api_common.go)
|
|
||||||
// by [authors](https://github.com/nsf/termbox-go/blob/master/AUTHORS)
|
|
||||||
// under [license](https://github.com/nsf/termbox-go/blob/master/LICENSE)
|
|
||||||
|
|
||||||
package termui
|
package termui
|
||||||
|
|
||||||
import "github.com/nsf/termbox-go"
|
import (
|
||||||
|
"path"
|
||||||
|
"strconv"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
/***********************************termbox-go**************************************/
|
"github.com/nsf/termbox-go"
|
||||||
|
|
||||||
type (
|
|
||||||
EventType uint8
|
|
||||||
Modifier uint8
|
|
||||||
Key uint16
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// This type represents a termbox event. The 'Mod', 'Key' and 'Ch' fields are
|
|
||||||
// valid if 'Type' is EventKey. The 'Width' and 'Height' fields are valid if
|
|
||||||
// 'Type' is EventResize. The 'Err' field is valid if 'Type' is EventError.
|
|
||||||
type Event struct {
|
type Event struct {
|
||||||
Type EventType // one of Event* constants
|
Type string
|
||||||
Mod Modifier // one of Mod* constants or 0
|
Path string
|
||||||
Key Key // one of Key* constants, invalid if 'Ch' is not 0
|
From string
|
||||||
Ch rune // a unicode character
|
To string
|
||||||
Width int // width of the screen
|
Data interface{}
|
||||||
Height int // height of the screen
|
Time int64
|
||||||
Err error // error in case if input failed
|
|
||||||
MouseX int // x coord of mouse
|
|
||||||
MouseY int // y coord of mouse
|
|
||||||
N int // number of bytes written when getting a raw event
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
var sysEvtChs []chan Event
|
||||||
KeyF1 Key = 0xFFFF - iota
|
|
||||||
KeyF2
|
|
||||||
KeyF3
|
|
||||||
KeyF4
|
|
||||||
KeyF5
|
|
||||||
KeyF6
|
|
||||||
KeyF7
|
|
||||||
KeyF8
|
|
||||||
KeyF9
|
|
||||||
KeyF10
|
|
||||||
KeyF11
|
|
||||||
KeyF12
|
|
||||||
KeyInsert
|
|
||||||
KeyDelete
|
|
||||||
KeyHome
|
|
||||||
KeyEnd
|
|
||||||
KeyPgup
|
|
||||||
KeyPgdn
|
|
||||||
KeyArrowUp
|
|
||||||
KeyArrowDown
|
|
||||||
KeyArrowLeft
|
|
||||||
KeyArrowRight
|
|
||||||
key_min // see terminfo
|
|
||||||
MouseLeft
|
|
||||||
MouseMiddle
|
|
||||||
MouseRight
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
type EvtKbd struct {
|
||||||
KeyCtrlTilde Key = 0x00
|
KeyStr string
|
||||||
KeyCtrl2 Key = 0x00
|
|
||||||
KeyCtrlSpace Key = 0x00
|
|
||||||
KeyCtrlA Key = 0x01
|
|
||||||
KeyCtrlB Key = 0x02
|
|
||||||
KeyCtrlC Key = 0x03
|
|
||||||
KeyCtrlD Key = 0x04
|
|
||||||
KeyCtrlE Key = 0x05
|
|
||||||
KeyCtrlF Key = 0x06
|
|
||||||
KeyCtrlG Key = 0x07
|
|
||||||
KeyBackspace Key = 0x08
|
|
||||||
KeyCtrlH Key = 0x08
|
|
||||||
KeyTab Key = 0x09
|
|
||||||
KeyCtrlI Key = 0x09
|
|
||||||
KeyCtrlJ Key = 0x0A
|
|
||||||
KeyCtrlK Key = 0x0B
|
|
||||||
KeyCtrlL Key = 0x0C
|
|
||||||
KeyEnter Key = 0x0D
|
|
||||||
KeyCtrlM Key = 0x0D
|
|
||||||
KeyCtrlN Key = 0x0E
|
|
||||||
KeyCtrlO Key = 0x0F
|
|
||||||
KeyCtrlP Key = 0x10
|
|
||||||
KeyCtrlQ Key = 0x11
|
|
||||||
KeyCtrlR Key = 0x12
|
|
||||||
KeyCtrlS Key = 0x13
|
|
||||||
KeyCtrlT Key = 0x14
|
|
||||||
KeyCtrlU Key = 0x15
|
|
||||||
KeyCtrlV Key = 0x16
|
|
||||||
KeyCtrlW Key = 0x17
|
|
||||||
KeyCtrlX Key = 0x18
|
|
||||||
KeyCtrlY Key = 0x19
|
|
||||||
KeyCtrlZ Key = 0x1A
|
|
||||||
KeyEsc Key = 0x1B
|
|
||||||
KeyCtrlLsqBracket Key = 0x1B
|
|
||||||
KeyCtrl3 Key = 0x1B
|
|
||||||
KeyCtrl4 Key = 0x1C
|
|
||||||
KeyCtrlBackslash Key = 0x1C
|
|
||||||
KeyCtrl5 Key = 0x1D
|
|
||||||
KeyCtrlRsqBracket Key = 0x1D
|
|
||||||
KeyCtrl6 Key = 0x1E
|
|
||||||
KeyCtrl7 Key = 0x1F
|
|
||||||
KeyCtrlSlash Key = 0x1F
|
|
||||||
KeyCtrlUnderscore Key = 0x1F
|
|
||||||
KeySpace Key = 0x20
|
|
||||||
KeyBackspace2 Key = 0x7F
|
|
||||||
KeyCtrl8 Key = 0x7F
|
|
||||||
)
|
|
||||||
|
|
||||||
// Alt modifier constant, see Event.Mod field and SetInputMode function.
|
|
||||||
const (
|
|
||||||
ModAlt Modifier = 0x01
|
|
||||||
)
|
|
||||||
|
|
||||||
// Event type. See Event.Type field.
|
|
||||||
const (
|
|
||||||
EventKey EventType = iota
|
|
||||||
EventResize
|
|
||||||
EventMouse
|
|
||||||
EventError
|
|
||||||
EventInterrupt
|
|
||||||
EventRaw
|
|
||||||
EventNone
|
|
||||||
)
|
|
||||||
|
|
||||||
/**************************************end**************************************/
|
|
||||||
|
|
||||||
// convert termbox.Event to termui.Event
|
|
||||||
func uiEvt(e termbox.Event) Event {
|
|
||||||
event := Event{}
|
|
||||||
event.Type = EventType(e.Type)
|
|
||||||
event.Mod = Modifier(e.Mod)
|
|
||||||
event.Key = Key(e.Key)
|
|
||||||
event.Ch = e.Ch
|
|
||||||
event.Width = e.Width
|
|
||||||
event.Height = e.Height
|
|
||||||
event.Err = e.Err
|
|
||||||
event.MouseX = e.MouseX
|
|
||||||
event.MouseY = e.MouseY
|
|
||||||
event.N = e.N
|
|
||||||
|
|
||||||
return event
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var evtChs = make([]chan Event, 0)
|
func evtKbd(e termbox.Event) EvtKbd {
|
||||||
|
ek := EvtKbd{}
|
||||||
|
|
||||||
// EventCh returns an output-only event channel.
|
k := string(e.Ch)
|
||||||
// This function can be called many times (multiplexer).
|
pre := ""
|
||||||
func EventCh() <-chan Event {
|
mod := ""
|
||||||
out := make(chan Event)
|
|
||||||
evtChs = append(evtChs, out)
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
// turn on event listener
|
if e.Mod == termbox.ModAlt {
|
||||||
func evtListen() {
|
mod = "M-"
|
||||||
go func() {
|
}
|
||||||
for {
|
if e.Ch == 0 {
|
||||||
e := termbox.PollEvent()
|
if e.Key > 0xFFFF-12 {
|
||||||
// dispatch
|
k = "<f" + strconv.Itoa(0xFFFF-int(e.Key)+1) + ">"
|
||||||
for _, c := range evtChs {
|
} else if e.Key > 0xFFFF-25 {
|
||||||
go func(ch chan Event) {
|
ks := []string{"<insert>", "<delete>", "<home>", "<end>", "<previous>", "<next>", "<up>", "<down>", "<left>", "<right>"}
|
||||||
ch <- uiEvt(e)
|
k = ks[0xFFFF-int(e.Key)-12]
|
||||||
}(c)
|
}
|
||||||
|
|
||||||
|
if e.Key <= 0x7F {
|
||||||
|
pre = "C-"
|
||||||
|
k = string('a' - 1 + int(e.Key))
|
||||||
|
kmap := map[termbox.Key][2]string{
|
||||||
|
termbox.KeyCtrlSpace: {"C-", "<space>"},
|
||||||
|
termbox.KeyBackspace: {"", "<backspace>"},
|
||||||
|
termbox.KeyTab: {"", "<tab>"},
|
||||||
|
termbox.KeyEnter: {"", "<enter>"},
|
||||||
|
termbox.KeyEsc: {"", "<escape>"},
|
||||||
|
termbox.KeyCtrlBackslash: {"C-", "\\"},
|
||||||
|
termbox.KeyCtrlSlash: {"C-", "/"},
|
||||||
|
termbox.KeySpace: {"", "<space>"},
|
||||||
|
termbox.KeyCtrl8: {"C-", "8"},
|
||||||
}
|
}
|
||||||
}
|
if sk, ok := kmap[e.Key]; ok {
|
||||||
}()
|
pre = sk[0]
|
||||||
}
|
k = sk[1]
|
||||||
|
|
||||||
/*
|
|
||||||
// EventHandlers is a handler sequence
|
|
||||||
var EventHandlers []func(Event)
|
|
||||||
|
|
||||||
var signalQuit = make(chan bool)
|
|
||||||
|
|
||||||
// Quit sends quit signal to terminate termui
|
|
||||||
func Quit() {
|
|
||||||
signalQuit <- true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait listening to signalQuit, block operation.
|
|
||||||
func Wait() {
|
|
||||||
<-signalQuit
|
|
||||||
}
|
|
||||||
|
|
||||||
// RegEvtHandler register function into TSEventHandler sequence.
|
|
||||||
func RegEvtHandler(fn func(Event)) {
|
|
||||||
EventHandlers = append(EventHandlers, fn)
|
|
||||||
}
|
|
||||||
|
|
||||||
// EventLoop handles all events and
|
|
||||||
// redirects every event to callbacks in EventHandlers
|
|
||||||
func EventLoop() {
|
|
||||||
evt := make(chan termbox.Event)
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
evt <- termbox.PollEvent()
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case c := <-signalQuit:
|
|
||||||
defer func() { signalQuit <- c }()
|
|
||||||
return
|
|
||||||
case e := <-evt:
|
|
||||||
for _, fn := range EventHandlers {
|
|
||||||
fn(uiEvt(e))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ek.KeyStr = pre + mod + k
|
||||||
|
return ek
|
||||||
|
}
|
||||||
|
|
||||||
|
func crtTermboxEvt(e termbox.Event) Event {
|
||||||
|
systypemap := map[termbox.EventType]string{
|
||||||
|
termbox.EventKey: "keyboard",
|
||||||
|
termbox.EventResize: "window",
|
||||||
|
termbox.EventMouse: "mouse",
|
||||||
|
termbox.EventError: "error",
|
||||||
|
termbox.EventInterrupt: "interrupt",
|
||||||
|
}
|
||||||
|
ne := Event{From: "/sys", Time: time.Now().Unix()}
|
||||||
|
typ := e.Type
|
||||||
|
ne.Type = systypemap[typ]
|
||||||
|
|
||||||
|
switch typ {
|
||||||
|
case termbox.EventKey:
|
||||||
|
kbd := evtKbd(e)
|
||||||
|
ne.Path = "/sys/kbd/" + kbd.KeyStr
|
||||||
|
ne.Data = kbd
|
||||||
|
case termbox.EventResize:
|
||||||
|
wnd := EvtWnd{}
|
||||||
|
wnd.Width = e.Width
|
||||||
|
wnd.Height = e.Height
|
||||||
|
ne.Path = "/sys/wnd/resize"
|
||||||
|
ne.Data = wnd
|
||||||
|
case termbox.EventError:
|
||||||
|
err := EvtErr(e.Err)
|
||||||
|
ne.Path = "/sys/err"
|
||||||
|
ne.Data = err
|
||||||
|
case termbox.EventMouse:
|
||||||
|
m := EvtMouse{}
|
||||||
|
m.X = e.MouseX
|
||||||
|
m.Y = e.MouseY
|
||||||
|
ne.Path = "/sys/mouse"
|
||||||
|
ne.Data = m
|
||||||
|
}
|
||||||
|
return ne
|
||||||
|
}
|
||||||
|
|
||||||
|
type EvtWnd struct {
|
||||||
|
Width int
|
||||||
|
Height int
|
||||||
|
}
|
||||||
|
|
||||||
|
type EvtMouse struct {
|
||||||
|
X int
|
||||||
|
Y int
|
||||||
|
Press string
|
||||||
|
}
|
||||||
|
|
||||||
|
type EvtErr error
|
||||||
|
|
||||||
|
func hookTermboxEvt() {
|
||||||
|
for {
|
||||||
|
e := termbox.PollEvent()
|
||||||
|
|
||||||
|
for _, c := range sysEvtChs {
|
||||||
|
go func(ch chan Event) {
|
||||||
|
ch <- crtTermboxEvt(e)
|
||||||
|
}(c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSysEvtCh() chan Event {
|
||||||
|
ec := make(chan Event)
|
||||||
|
sysEvtChs = append(sysEvtChs, ec)
|
||||||
|
return ec
|
||||||
|
}
|
||||||
|
|
||||||
|
var DefaultEvtStream = NewEvtStream()
|
||||||
|
|
||||||
|
type EvtStream struct {
|
||||||
|
sync.RWMutex
|
||||||
|
srcMap map[string]chan Event
|
||||||
|
stream chan Event
|
||||||
|
wg sync.WaitGroup
|
||||||
|
sigStopLoop chan Event
|
||||||
|
Handlers map[string]func(Event)
|
||||||
|
hook func(Event)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewEvtStream() *EvtStream {
|
||||||
|
return &EvtStream{
|
||||||
|
srcMap: make(map[string]chan Event),
|
||||||
|
stream: make(chan Event),
|
||||||
|
Handlers: make(map[string]func(Event)),
|
||||||
|
sigStopLoop: make(chan Event),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (es *EvtStream) Init() {
|
||||||
|
es.Merge("internal", es.sigStopLoop)
|
||||||
|
go func() {
|
||||||
|
es.wg.Wait()
|
||||||
|
close(es.stream)
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
func cleanPath(p string) string {
|
||||||
|
if p == "" {
|
||||||
|
return "/"
|
||||||
|
}
|
||||||
|
if p[0] != '/' {
|
||||||
|
p = "/" + p
|
||||||
|
}
|
||||||
|
return path.Clean(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func isPathMatch(pattern, path string) bool {
|
||||||
|
if len(pattern) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
n := len(pattern)
|
||||||
|
return len(path) >= n && path[0:n] == pattern
|
||||||
|
}
|
||||||
|
|
||||||
|
func (es *EvtStream) Merge(name string, ec chan Event) {
|
||||||
|
es.Lock()
|
||||||
|
defer es.Unlock()
|
||||||
|
|
||||||
|
es.wg.Add(1)
|
||||||
|
es.srcMap[name] = ec
|
||||||
|
|
||||||
|
go func(a chan Event) {
|
||||||
|
for n := range a {
|
||||||
|
n.From = name
|
||||||
|
es.stream <- n
|
||||||
|
}
|
||||||
|
es.wg.Done()
|
||||||
|
}(ec)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (es *EvtStream) Handle(path string, handler func(Event)) {
|
||||||
|
es.Handlers[cleanPath(path)] = handler
|
||||||
|
}
|
||||||
|
|
||||||
|
func findMatch(mux map[string]func(Event), path string) string {
|
||||||
|
n := -1
|
||||||
|
pattern := ""
|
||||||
|
for m := range mux {
|
||||||
|
if !isPathMatch(m, path) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if len(m) > n {
|
||||||
|
pattern = m
|
||||||
|
n = len(m)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pattern
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (es *EvtStream) match(path string) string {
|
||||||
|
return findMatch(es.Handlers, path)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (es *EvtStream) Hook(f func(Event)) {
|
||||||
|
es.hook = f
|
||||||
|
}
|
||||||
|
|
||||||
|
func (es *EvtStream) Loop() {
|
||||||
|
for e := range es.stream {
|
||||||
|
switch e.Path {
|
||||||
|
case "/sig/stoploop":
|
||||||
|
return
|
||||||
|
}
|
||||||
|
go func(a Event) {
|
||||||
|
es.RLock()
|
||||||
|
defer es.RUnlock()
|
||||||
|
if pattern := es.match(a.Path); pattern != "" {
|
||||||
|
es.Handlers[pattern](a)
|
||||||
|
}
|
||||||
|
}(e)
|
||||||
|
if es.hook != nil {
|
||||||
|
es.hook(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (es *EvtStream) StopLoop() {
|
||||||
|
go func() {
|
||||||
|
e := Event{
|
||||||
|
Path: "/sig/stoploop",
|
||||||
|
}
|
||||||
|
es.sigStopLoop <- e
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
func Merge(name string, ec chan Event) {
|
||||||
|
DefaultEvtStream.Merge(name, ec)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Handle(path string, handler func(Event)) {
|
||||||
|
DefaultEvtStream.Handle(path, handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Loop() {
|
||||||
|
DefaultEvtStream.Loop()
|
||||||
|
}
|
||||||
|
|
||||||
|
func StopLoop() {
|
||||||
|
DefaultEvtStream.StopLoop()
|
||||||
|
}
|
||||||
|
|
||||||
|
type EvtTimer struct {
|
||||||
|
Duration time.Duration
|
||||||
|
Count uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTimerCh(du time.Duration) chan Event {
|
||||||
|
t := make(chan Event)
|
||||||
|
|
||||||
|
go func(a chan Event) {
|
||||||
|
n := uint64(0)
|
||||||
|
for {
|
||||||
|
n++
|
||||||
|
time.Sleep(du)
|
||||||
|
e := Event{}
|
||||||
|
e.Type = "timer"
|
||||||
|
e.Path = "/timer/" + du.String()
|
||||||
|
e.Time = time.Now().Unix()
|
||||||
|
e.Data = EvtTimer{
|
||||||
|
Duration: du,
|
||||||
|
Count: n,
|
||||||
|
}
|
||||||
|
t <- e
|
||||||
|
|
||||||
|
}
|
||||||
|
}(t)
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
var DefualtHandler = func(e Event) {
|
||||||
|
}
|
||||||
|
|
||||||
|
var usrEvtCh = make(chan Event)
|
||||||
|
|
||||||
|
func SendCustomEvt(path string, data interface{}) {
|
||||||
|
e := Event{}
|
||||||
|
e.Path = path
|
||||||
|
e.Data = data
|
||||||
|
e.Time = time.Now().Unix()
|
||||||
|
usrEvtCh <- e
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
|
||||||
28
Godeps/_workspace/src/github.com/gizak/termui/events_test.go
generated
vendored
|
|
@ -1,28 +0,0 @@
|
||||||
// Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved.
|
|
||||||
// Use of this source code is governed by a MIT license that can
|
|
||||||
// be found in the LICENSE file.
|
|
||||||
//
|
|
||||||
// Portions of this file uses [termbox-go](https://github.com/nsf/termbox-go/blob/54b74d087b7c397c402d0e3b66d2ccb6eaf5c2b4/api_common.go)
|
|
||||||
// by [authors](https://github.com/nsf/termbox-go/blob/master/AUTHORS)
|
|
||||||
// under [license](https://github.com/nsf/termbox-go/blob/master/LICENSE)
|
|
||||||
|
|
||||||
package termui
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
termbox "github.com/nsf/termbox-go"
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
type boxEvent termbox.Event
|
|
||||||
|
|
||||||
func TestUiEvt(t *testing.T) {
|
|
||||||
err := errors.New("This is a mock error")
|
|
||||||
event := boxEvent{3, 5, 2, 'H', 200, 500, err, 50, 30, 2}
|
|
||||||
expetced := Event{3, 5, 2, 'H', 200, 500, err, 50, 30, 2}
|
|
||||||
|
|
||||||
// We need to do that ugly casting so that vet does not complain
|
|
||||||
assert.Equal(t, uiEvt(termbox.Event(event)), expetced)
|
|
||||||
}
|
|
||||||
35
Godeps/_workspace/src/github.com/gizak/termui/example/barchart.go
generated
vendored
|
|
@ -1,35 +0,0 @@
|
||||||
// Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved.
|
|
||||||
// Use of this source code is governed by a MIT license that can
|
|
||||||
// be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import "github.com/gizak/termui"
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
err := termui.Init()
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
defer termui.Close()
|
|
||||||
|
|
||||||
termui.UseTheme("helloworld")
|
|
||||||
|
|
||||||
bc := termui.NewBarChart()
|
|
||||||
data := []int{3, 2, 5, 3, 9, 5, 3, 2, 5, 8, 3, 2, 4, 5, 3, 2, 5, 7, 5, 3, 2, 6, 7, 4, 6, 3, 6, 7, 8, 3, 6, 4, 5, 3, 2, 4, 6, 4, 8, 5, 9, 4, 3, 6, 5, 3, 6}
|
|
||||||
bclabels := []string{"S0", "S1", "S2", "S3", "S4", "S5"}
|
|
||||||
bc.Border.Label = "Bar Chart"
|
|
||||||
bc.Data = data
|
|
||||||
bc.Width = 26
|
|
||||||
bc.Height = 10
|
|
||||||
bc.DataLabels = bclabels
|
|
||||||
bc.TextColor = termui.ColorGreen
|
|
||||||
bc.BarColor = termui.ColorRed
|
|
||||||
bc.NumColor = termui.ColorYellow
|
|
||||||
|
|
||||||
termui.Render(bc)
|
|
||||||
|
|
||||||
<-termui.EventCh()
|
|
||||||
}
|
|
||||||
BIN
Godeps/_workspace/src/github.com/gizak/termui/example/barchart.png
generated
vendored
|
Before Width: | Height: | Size: 15 KiB |
BIN
Godeps/_workspace/src/github.com/gizak/termui/example/dashboard.gif
generated
vendored
|
Before Width: | Height: | Size: 443 KiB |
148
Godeps/_workspace/src/github.com/gizak/termui/example/dashboard.go
generated
vendored
|
|
@ -1,148 +0,0 @@
|
||||||
// Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved.
|
|
||||||
// Use of this source code is governed by a MIT license that can
|
|
||||||
// be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import ui "github.com/gizak/termui"
|
|
||||||
import "math"
|
|
||||||
|
|
||||||
import "time"
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
err := ui.Init()
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
defer ui.Close()
|
|
||||||
|
|
||||||
p := ui.NewPar(":PRESS q TO QUIT DEMO")
|
|
||||||
p.Height = 3
|
|
||||||
p.Width = 50
|
|
||||||
p.TextFgColor = ui.ColorWhite
|
|
||||||
p.Border.Label = "Text Box"
|
|
||||||
p.Border.FgColor = ui.ColorCyan
|
|
||||||
|
|
||||||
strs := []string{"[0] gizak/termui", "[1] editbox.go", "[2] iterrupt.go", "[3] keyboard.go", "[4] output.go", "[5] random_out.go", "[6] dashboard.go", "[7] nsf/termbox-go"}
|
|
||||||
list := ui.NewList()
|
|
||||||
list.Items = strs
|
|
||||||
list.ItemFgColor = ui.ColorYellow
|
|
||||||
list.Border.Label = "List"
|
|
||||||
list.Height = 7
|
|
||||||
list.Width = 25
|
|
||||||
list.Y = 4
|
|
||||||
|
|
||||||
g := ui.NewGauge()
|
|
||||||
g.Percent = 50
|
|
||||||
g.Width = 50
|
|
||||||
g.Height = 3
|
|
||||||
g.Y = 11
|
|
||||||
g.Border.Label = "Gauge"
|
|
||||||
g.BarColor = ui.ColorRed
|
|
||||||
g.Border.FgColor = ui.ColorWhite
|
|
||||||
g.Border.LabelFgColor = ui.ColorCyan
|
|
||||||
|
|
||||||
spark := ui.Sparkline{}
|
|
||||||
spark.Height = 1
|
|
||||||
spark.Title = "srv 0:"
|
|
||||||
spdata := []int{4, 2, 1, 6, 3, 9, 1, 4, 2, 15, 14, 9, 8, 6, 10, 13, 15, 12, 10, 5, 3, 6, 1, 7, 10, 10, 14, 13, 6, 4, 2, 1, 6, 3, 9, 1, 4, 2, 15, 14, 9, 8, 6, 10, 13, 15, 12, 10, 5, 3, 6, 1, 7, 10, 10, 14, 13, 6, 4, 2, 1, 6, 3, 9, 1, 4, 2, 15, 14, 9, 8, 6, 10, 13, 15, 12, 10, 5, 3, 6, 1, 7, 10, 10, 14, 13, 6, 4, 2, 1, 6, 3, 9, 1, 4, 2, 15, 14, 9, 8, 6, 10, 13, 15, 12, 10, 5, 3, 6, 1, 7, 10, 10, 14, 13, 6}
|
|
||||||
spark.Data = spdata
|
|
||||||
spark.LineColor = ui.ColorCyan
|
|
||||||
spark.TitleColor = ui.ColorWhite
|
|
||||||
|
|
||||||
spark1 := ui.Sparkline{}
|
|
||||||
spark1.Height = 1
|
|
||||||
spark1.Title = "srv 1:"
|
|
||||||
spark1.Data = spdata
|
|
||||||
spark1.TitleColor = ui.ColorWhite
|
|
||||||
spark1.LineColor = ui.ColorRed
|
|
||||||
|
|
||||||
sp := ui.NewSparklines(spark, spark1)
|
|
||||||
sp.Width = 25
|
|
||||||
sp.Height = 7
|
|
||||||
sp.Border.Label = "Sparkline"
|
|
||||||
sp.Y = 4
|
|
||||||
sp.X = 25
|
|
||||||
|
|
||||||
sinps := (func() []float64 {
|
|
||||||
n := 220
|
|
||||||
ps := make([]float64, n)
|
|
||||||
for i := range ps {
|
|
||||||
ps[i] = 1 + math.Sin(float64(i)/5)
|
|
||||||
}
|
|
||||||
return ps
|
|
||||||
})()
|
|
||||||
|
|
||||||
lc := ui.NewLineChart()
|
|
||||||
lc.Border.Label = "dot-mode Line Chart"
|
|
||||||
lc.Data = sinps
|
|
||||||
lc.Width = 50
|
|
||||||
lc.Height = 11
|
|
||||||
lc.X = 0
|
|
||||||
lc.Y = 14
|
|
||||||
lc.AxesColor = ui.ColorWhite
|
|
||||||
lc.LineColor = ui.ColorRed | ui.AttrBold
|
|
||||||
lc.Mode = "dot"
|
|
||||||
|
|
||||||
bc := ui.NewBarChart()
|
|
||||||
bcdata := []int{3, 2, 5, 3, 9, 5, 3, 2, 5, 8, 3, 2, 4, 5, 3, 2, 5, 7, 5, 3, 2, 6, 7, 4, 6, 3, 6, 7, 8, 3, 6, 4, 5, 3, 2, 4, 6, 4, 8, 5, 9, 4, 3, 6, 5, 3, 6}
|
|
||||||
bclabels := []string{"S0", "S1", "S2", "S3", "S4", "S5"}
|
|
||||||
bc.Border.Label = "Bar Chart"
|
|
||||||
bc.Width = 26
|
|
||||||
bc.Height = 10
|
|
||||||
bc.X = 51
|
|
||||||
bc.Y = 0
|
|
||||||
bc.DataLabels = bclabels
|
|
||||||
bc.BarColor = ui.ColorGreen
|
|
||||||
bc.NumColor = ui.ColorBlack
|
|
||||||
|
|
||||||
lc1 := ui.NewLineChart()
|
|
||||||
lc1.Border.Label = "braille-mode Line Chart"
|
|
||||||
lc1.Data = sinps
|
|
||||||
lc1.Width = 26
|
|
||||||
lc1.Height = 11
|
|
||||||
lc1.X = 51
|
|
||||||
lc1.Y = 14
|
|
||||||
lc1.AxesColor = ui.ColorWhite
|
|
||||||
lc1.LineColor = ui.ColorYellow | ui.AttrBold
|
|
||||||
|
|
||||||
p1 := ui.NewPar("Hey!\nI am a borderless block!")
|
|
||||||
p1.HasBorder = false
|
|
||||||
p1.Width = 26
|
|
||||||
p1.Height = 2
|
|
||||||
p1.TextFgColor = ui.ColorMagenta
|
|
||||||
p1.X = 52
|
|
||||||
p1.Y = 11
|
|
||||||
|
|
||||||
draw := func(t int) {
|
|
||||||
g.Percent = t % 101
|
|
||||||
list.Items = strs[t%9:]
|
|
||||||
sp.Lines[0].Data = spdata[:30+t%50]
|
|
||||||
sp.Lines[1].Data = spdata[:35+t%50]
|
|
||||||
lc.Data = sinps[t/2:]
|
|
||||||
lc1.Data = sinps[2*t:]
|
|
||||||
bc.Data = bcdata[t/2%10:]
|
|
||||||
ui.Render(p, list, g, sp, lc, bc, lc1, p1)
|
|
||||||
}
|
|
||||||
|
|
||||||
evt := ui.EventCh()
|
|
||||||
|
|
||||||
i := 0
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case e := <-evt:
|
|
||||||
if e.Type == ui.EventKey && e.Ch == 'q' {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
draw(i)
|
|
||||||
i++
|
|
||||||
if i == 102 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
time.Sleep(time.Second / 2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
62
Godeps/_workspace/src/github.com/gizak/termui/example/gauge.go
generated
vendored
|
|
@ -1,62 +0,0 @@
|
||||||
// Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved.
|
|
||||||
// Use of this source code is governed by a MIT license that can
|
|
||||||
// be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import "github.com/gizak/termui"
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
err := termui.Init()
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
defer termui.Close()
|
|
||||||
|
|
||||||
termui.UseTheme("helloworld")
|
|
||||||
|
|
||||||
g0 := termui.NewGauge()
|
|
||||||
g0.Percent = 40
|
|
||||||
g0.Width = 50
|
|
||||||
g0.Height = 3
|
|
||||||
g0.Border.Label = "Slim Gauge"
|
|
||||||
g0.BarColor = termui.ColorRed
|
|
||||||
g0.Border.FgColor = termui.ColorWhite
|
|
||||||
g0.Border.LabelFgColor = termui.ColorCyan
|
|
||||||
|
|
||||||
g2 := termui.NewGauge()
|
|
||||||
g2.Percent = 60
|
|
||||||
g2.Width = 50
|
|
||||||
g2.Height = 3
|
|
||||||
g2.PercentColor = termui.ColorBlue
|
|
||||||
g2.Y = 3
|
|
||||||
g2.Border.Label = "Slim Gauge"
|
|
||||||
g2.BarColor = termui.ColorYellow
|
|
||||||
g2.Border.FgColor = termui.ColorWhite
|
|
||||||
|
|
||||||
g1 := termui.NewGauge()
|
|
||||||
g1.Percent = 30
|
|
||||||
g1.Width = 50
|
|
||||||
g1.Height = 5
|
|
||||||
g1.Y = 6
|
|
||||||
g1.Border.Label = "Big Gauge"
|
|
||||||
g1.PercentColor = termui.ColorYellow
|
|
||||||
g1.BarColor = termui.ColorGreen
|
|
||||||
g1.Border.FgColor = termui.ColorWhite
|
|
||||||
g1.Border.LabelFgColor = termui.ColorMagenta
|
|
||||||
|
|
||||||
g3 := termui.NewGauge()
|
|
||||||
g3.Percent = 50
|
|
||||||
g3.Width = 50
|
|
||||||
g3.Height = 3
|
|
||||||
g3.Y = 11
|
|
||||||
g3.Border.Label = "Gauge with custom label"
|
|
||||||
g3.Label = "{{percent}}% (100MBs free)"
|
|
||||||
g3.LabelAlign = termui.AlignRight
|
|
||||||
|
|
||||||
termui.Render(g0, g1, g2, g3)
|
|
||||||
|
|
||||||
<-termui.EventCh()
|
|
||||||
}
|
|
||||||
BIN
Godeps/_workspace/src/github.com/gizak/termui/example/gauge.png
generated
vendored
|
Before Width: | Height: | Size: 32 KiB |
BIN
Godeps/_workspace/src/github.com/gizak/termui/example/grid.gif
generated
vendored
|
Before Width: | Height: | Size: 782 KiB |
134
Godeps/_workspace/src/github.com/gizak/termui/example/grid.go
generated
vendored
|
|
@ -1,134 +0,0 @@
|
||||||
// Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved.
|
|
||||||
// Use of this source code is governed by a MIT license that can
|
|
||||||
// be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import ui "github.com/gizak/termui"
|
|
||||||
import "math"
|
|
||||||
import "time"
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
err := ui.Init()
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
defer ui.Close()
|
|
||||||
|
|
||||||
sinps := (func() []float64 {
|
|
||||||
n := 400
|
|
||||||
ps := make([]float64, n)
|
|
||||||
for i := range ps {
|
|
||||||
ps[i] = 1 + math.Sin(float64(i)/5)
|
|
||||||
}
|
|
||||||
return ps
|
|
||||||
})()
|
|
||||||
sinpsint := (func() []int {
|
|
||||||
ps := make([]int, len(sinps))
|
|
||||||
for i, v := range sinps {
|
|
||||||
ps[i] = int(100*v + 10)
|
|
||||||
}
|
|
||||||
return ps
|
|
||||||
})()
|
|
||||||
|
|
||||||
ui.UseTheme("helloworld")
|
|
||||||
|
|
||||||
spark := ui.Sparkline{}
|
|
||||||
spark.Height = 8
|
|
||||||
spdata := sinpsint
|
|
||||||
spark.Data = spdata[:100]
|
|
||||||
spark.LineColor = ui.ColorCyan
|
|
||||||
spark.TitleColor = ui.ColorWhite
|
|
||||||
|
|
||||||
sp := ui.NewSparklines(spark)
|
|
||||||
sp.Height = 11
|
|
||||||
sp.Border.Label = "Sparkline"
|
|
||||||
|
|
||||||
lc := ui.NewLineChart()
|
|
||||||
lc.Border.Label = "braille-mode Line Chart"
|
|
||||||
lc.Data = sinps
|
|
||||||
lc.Height = 11
|
|
||||||
lc.AxesColor = ui.ColorWhite
|
|
||||||
lc.LineColor = ui.ColorYellow | ui.AttrBold
|
|
||||||
|
|
||||||
gs := make([]*ui.Gauge, 3)
|
|
||||||
for i := range gs {
|
|
||||||
gs[i] = ui.NewGauge()
|
|
||||||
gs[i].Height = 2
|
|
||||||
gs[i].HasBorder = false
|
|
||||||
gs[i].Percent = i * 10
|
|
||||||
gs[i].PaddingBottom = 1
|
|
||||||
gs[i].BarColor = ui.ColorRed
|
|
||||||
}
|
|
||||||
|
|
||||||
ls := ui.NewList()
|
|
||||||
ls.HasBorder = false
|
|
||||||
ls.Items = []string{
|
|
||||||
"[1] Downloading File 1",
|
|
||||||
"", // == \newline
|
|
||||||
"[2] Downloading File 2",
|
|
||||||
"",
|
|
||||||
"[3] Uploading File 3",
|
|
||||||
}
|
|
||||||
ls.Height = 5
|
|
||||||
|
|
||||||
par := ui.NewPar("<> This row has 3 columns\n<- Widgets can be stacked up like left side\n<- Stacked widgets are treated as a single widget")
|
|
||||||
par.Height = 5
|
|
||||||
par.Border.Label = "Demonstration"
|
|
||||||
|
|
||||||
// build layout
|
|
||||||
ui.Body.AddRows(
|
|
||||||
ui.NewRow(
|
|
||||||
ui.NewCol(6, 0, sp),
|
|
||||||
ui.NewCol(6, 0, lc)),
|
|
||||||
ui.NewRow(
|
|
||||||
ui.NewCol(3, 0, ls),
|
|
||||||
ui.NewCol(3, 0, gs[0], gs[1], gs[2]),
|
|
||||||
ui.NewCol(6, 0, par)))
|
|
||||||
|
|
||||||
// calculate layout
|
|
||||||
ui.Body.Align()
|
|
||||||
|
|
||||||
done := make(chan bool)
|
|
||||||
redraw := make(chan bool)
|
|
||||||
|
|
||||||
update := func() {
|
|
||||||
for i := 0; i < 103; i++ {
|
|
||||||
for _, g := range gs {
|
|
||||||
g.Percent = (g.Percent + 3) % 100
|
|
||||||
}
|
|
||||||
|
|
||||||
sp.Lines[0].Data = spdata[:100+i]
|
|
||||||
lc.Data = sinps[2*i:]
|
|
||||||
|
|
||||||
time.Sleep(time.Second / 2)
|
|
||||||
redraw <- true
|
|
||||||
}
|
|
||||||
done <- true
|
|
||||||
}
|
|
||||||
|
|
||||||
evt := ui.EventCh()
|
|
||||||
|
|
||||||
ui.Render(ui.Body)
|
|
||||||
go update()
|
|
||||||
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case e := <-evt:
|
|
||||||
if e.Type == ui.EventKey && e.Ch == 'q' {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if e.Type == ui.EventResize {
|
|
||||||
ui.Body.Width = ui.TermWidth()
|
|
||||||
ui.Body.Align()
|
|
||||||
go func() { redraw <- true }()
|
|
||||||
}
|
|
||||||
case <-done:
|
|
||||||
return
|
|
||||||
case <-redraw:
|
|
||||||
ui.Render(ui.Body)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
68
Godeps/_workspace/src/github.com/gizak/termui/example/linechart.go
generated
vendored
|
|
@ -1,68 +0,0 @@
|
||||||
// Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved.
|
|
||||||
// Use of this source code is governed by a MIT license that can
|
|
||||||
// be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"math"
|
|
||||||
|
|
||||||
"github.com/gizak/termui"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
err := termui.Init()
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
defer termui.Close()
|
|
||||||
|
|
||||||
termui.UseTheme("helloworld")
|
|
||||||
|
|
||||||
sinps := (func() []float64 {
|
|
||||||
n := 220
|
|
||||||
ps := make([]float64, n)
|
|
||||||
for i := range ps {
|
|
||||||
ps[i] = 1 + math.Sin(float64(i)/5)
|
|
||||||
}
|
|
||||||
return ps
|
|
||||||
})()
|
|
||||||
|
|
||||||
lc0 := termui.NewLineChart()
|
|
||||||
lc0.Border.Label = "braille-mode Line Chart"
|
|
||||||
lc0.Data = sinps
|
|
||||||
lc0.Width = 50
|
|
||||||
lc0.Height = 12
|
|
||||||
lc0.X = 0
|
|
||||||
lc0.Y = 0
|
|
||||||
lc0.AxesColor = termui.ColorWhite
|
|
||||||
lc0.LineColor = termui.ColorGreen | termui.AttrBold
|
|
||||||
|
|
||||||
lc1 := termui.NewLineChart()
|
|
||||||
lc1.Border.Label = "dot-mode Line Chart"
|
|
||||||
lc1.Mode = "dot"
|
|
||||||
lc1.Data = sinps
|
|
||||||
lc1.Width = 26
|
|
||||||
lc1.Height = 12
|
|
||||||
lc1.X = 51
|
|
||||||
lc1.DotStyle = '+'
|
|
||||||
lc1.AxesColor = termui.ColorWhite
|
|
||||||
lc1.LineColor = termui.ColorYellow | termui.AttrBold
|
|
||||||
|
|
||||||
lc2 := termui.NewLineChart()
|
|
||||||
lc2.Border.Label = "dot-mode Line Chart"
|
|
||||||
lc2.Mode = "dot"
|
|
||||||
lc2.Data = sinps[4:]
|
|
||||||
lc2.Width = 77
|
|
||||||
lc2.Height = 16
|
|
||||||
lc2.X = 0
|
|
||||||
lc2.Y = 12
|
|
||||||
lc2.AxesColor = termui.ColorWhite
|
|
||||||
lc2.LineColor = termui.ColorCyan | termui.AttrBold
|
|
||||||
|
|
||||||
termui.Render(lc0, lc1, lc2)
|
|
||||||
|
|
||||||
<-termui.EventCh()
|
|
||||||
}
|
|
||||||
BIN
Godeps/_workspace/src/github.com/gizak/termui/example/linechart.png
generated
vendored
|
Before Width: | Height: | Size: 136 KiB |
41
Godeps/_workspace/src/github.com/gizak/termui/example/list.go
generated
vendored
|
|
@ -1,41 +0,0 @@
|
||||||
// Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved.
|
|
||||||
// Use of this source code is governed by a MIT license that can
|
|
||||||
// be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import "github.com/gizak/termui"
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
err := termui.Init()
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
defer termui.Close()
|
|
||||||
|
|
||||||
termui.UseTheme("helloworld")
|
|
||||||
|
|
||||||
strs := []string{
|
|
||||||
"[0] github.com/gizak/termui",
|
|
||||||
"[1] 你好,世界",
|
|
||||||
"[2] こんにちは世界",
|
|
||||||
"[3] keyboard.go",
|
|
||||||
"[4] output.go",
|
|
||||||
"[5] random_out.go",
|
|
||||||
"[6] dashboard.go",
|
|
||||||
"[7] nsf/termbox-go"}
|
|
||||||
|
|
||||||
ls := termui.NewList()
|
|
||||||
ls.Items = strs
|
|
||||||
ls.ItemFgColor = termui.ColorYellow
|
|
||||||
ls.Border.Label = "List"
|
|
||||||
ls.Height = 7
|
|
||||||
ls.Width = 25
|
|
||||||
ls.Y = 0
|
|
||||||
|
|
||||||
termui.Render(ls)
|
|
||||||
|
|
||||||
<-termui.EventCh()
|
|
||||||
}
|
|
||||||
BIN
Godeps/_workspace/src/github.com/gizak/termui/example/list.png
generated
vendored
|
Before Width: | Height: | Size: 36 KiB |
50
Godeps/_workspace/src/github.com/gizak/termui/example/mbarchart.go
generated
vendored
|
|
@ -1,50 +0,0 @@
|
||||||
// Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved.
|
|
||||||
// Use of this source code is governed by a MIT license that can
|
|
||||||
// be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import "github.com/gizak/termui"
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
err := termui.Init()
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
defer termui.Close()
|
|
||||||
|
|
||||||
termui.UseTheme("helloworld")
|
|
||||||
|
|
||||||
bc := termui.NewMBarChart()
|
|
||||||
math := []int{90, 85, 90, 80}
|
|
||||||
english := []int{70, 85, 75, 60}
|
|
||||||
science := []int{75, 60, 80, 85}
|
|
||||||
compsci := []int{100, 100, 100, 100}
|
|
||||||
bc.Data[0] = math
|
|
||||||
bc.Data[1] = english
|
|
||||||
bc.Data[2] = science
|
|
||||||
bc.Data[3] = compsci
|
|
||||||
studentsName := []string{"Ken", "Rob", "Dennis", "Linus"}
|
|
||||||
bc.Border.Label = "Student's Marks X-Axis=Name Y-Axis=Marks[Math,English,Science,ComputerScience] in %"
|
|
||||||
bc.Width = 100
|
|
||||||
bc.Height = 50
|
|
||||||
bc.Y = 10
|
|
||||||
bc.BarWidth = 10
|
|
||||||
bc.DataLabels = studentsName
|
|
||||||
bc.ShowScale = true //Show y_axis scale value (min and max)
|
|
||||||
bc.SetMax(400)
|
|
||||||
|
|
||||||
bc.TextColor = termui.ColorGreen //this is color for label (x-axis)
|
|
||||||
bc.BarColor[3] = termui.ColorGreen //BarColor for computerscience
|
|
||||||
bc.BarColor[1] = termui.ColorYellow //Bar Color for english
|
|
||||||
bc.NumColor[3] = termui.ColorRed // Num color for computerscience
|
|
||||||
bc.NumColor[1] = termui.ColorRed // num color for english
|
|
||||||
|
|
||||||
//Other colors are automatically populated, btw All the students seems do well in computerscience. :p
|
|
||||||
|
|
||||||
termui.Render(bc)
|
|
||||||
|
|
||||||
<-termui.EventCh()
|
|
||||||
}
|
|
||||||
BIN
Godeps/_workspace/src/github.com/gizak/termui/example/mbarchart.png
generated
vendored
|
Before Width: | Height: | Size: 20 KiB |
48
Godeps/_workspace/src/github.com/gizak/termui/example/par.go
generated
vendored
|
|
@ -1,48 +0,0 @@
|
||||||
// Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved.
|
|
||||||
// Use of this source code is governed by a MIT license that can
|
|
||||||
// be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import "github.com/gizak/termui"
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
err := termui.Init()
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
defer termui.Close()
|
|
||||||
|
|
||||||
termui.UseTheme("helloworld")
|
|
||||||
|
|
||||||
par0 := termui.NewPar("Borderless Text")
|
|
||||||
par0.Height = 1
|
|
||||||
par0.Width = 20
|
|
||||||
par0.Y = 1
|
|
||||||
par0.HasBorder = false
|
|
||||||
|
|
||||||
par1 := termui.NewPar("你好,世界。")
|
|
||||||
par1.Height = 3
|
|
||||||
par1.Width = 17
|
|
||||||
par1.X = 20
|
|
||||||
par1.Border.Label = "标签"
|
|
||||||
|
|
||||||
par2 := termui.NewPar("Simple text\nwith label. It can be multilined with \\n or break automatically")
|
|
||||||
par2.Height = 5
|
|
||||||
par2.Width = 37
|
|
||||||
par2.Y = 4
|
|
||||||
par2.Border.Label = "Multiline"
|
|
||||||
par2.Border.FgColor = termui.ColorYellow
|
|
||||||
|
|
||||||
par3 := termui.NewPar("Long text with label and it is auto trimmed.")
|
|
||||||
par3.Height = 3
|
|
||||||
par3.Width = 37
|
|
||||||
par3.Y = 9
|
|
||||||
par3.Border.Label = "Auto Trim"
|
|
||||||
|
|
||||||
termui.Render(par0, par1, par2, par3)
|
|
||||||
|
|
||||||
<-termui.EventCh()
|
|
||||||
}
|
|
||||||
BIN
Godeps/_workspace/src/github.com/gizak/termui/example/par.png
generated
vendored
|
Before Width: | Height: | Size: 64 KiB |
65
Godeps/_workspace/src/github.com/gizak/termui/example/sparklines.go
generated
vendored
|
|
@ -1,65 +0,0 @@
|
||||||
// Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved.
|
|
||||||
// Use of this source code is governed by a MIT license that can
|
|
||||||
// be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import "github.com/gizak/termui"
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
err := termui.Init()
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
defer termui.Close()
|
|
||||||
|
|
||||||
termui.UseTheme("helloworld")
|
|
||||||
|
|
||||||
data := []int{4, 2, 1, 6, 3, 9, 1, 4, 2, 15, 14, 9, 8, 6, 10, 13, 15, 12, 10, 5, 3, 6, 1, 7, 10, 10, 14, 13, 6}
|
|
||||||
spl0 := termui.NewSparkline()
|
|
||||||
spl0.Data = data[3:]
|
|
||||||
spl0.Title = "Sparkline 0"
|
|
||||||
spl0.LineColor = termui.ColorGreen
|
|
||||||
|
|
||||||
// single
|
|
||||||
spls0 := termui.NewSparklines(spl0)
|
|
||||||
spls0.Height = 2
|
|
||||||
spls0.Width = 20
|
|
||||||
spls0.HasBorder = false
|
|
||||||
|
|
||||||
spl1 := termui.NewSparkline()
|
|
||||||
spl1.Data = data
|
|
||||||
spl1.Title = "Sparkline 1"
|
|
||||||
spl1.LineColor = termui.ColorRed
|
|
||||||
|
|
||||||
spl2 := termui.NewSparkline()
|
|
||||||
spl2.Data = data[5:]
|
|
||||||
spl2.Title = "Sparkline 2"
|
|
||||||
spl2.LineColor = termui.ColorMagenta
|
|
||||||
|
|
||||||
// group
|
|
||||||
spls1 := termui.NewSparklines(spl0, spl1, spl2)
|
|
||||||
spls1.Height = 8
|
|
||||||
spls1.Width = 20
|
|
||||||
spls1.Y = 3
|
|
||||||
spls1.Border.Label = "Group Sparklines"
|
|
||||||
|
|
||||||
spl3 := termui.NewSparkline()
|
|
||||||
spl3.Data = data
|
|
||||||
spl3.Title = "Enlarged Sparkline"
|
|
||||||
spl3.Height = 8
|
|
||||||
spl3.LineColor = termui.ColorYellow
|
|
||||||
|
|
||||||
spls2 := termui.NewSparklines(spl3)
|
|
||||||
spls2.Height = 11
|
|
||||||
spls2.Width = 30
|
|
||||||
spls2.Border.FgColor = termui.ColorCyan
|
|
||||||
spls2.X = 21
|
|
||||||
spls2.Border.Label = "Tweeked Sparkline"
|
|
||||||
|
|
||||||
termui.Render(spls0, spls1, spls2)
|
|
||||||
|
|
||||||
<-termui.EventCh()
|
|
||||||
}
|
|
||||||
BIN
Godeps/_workspace/src/github.com/gizak/termui/example/sparklines.png
generated
vendored
|
Before Width: | Height: | Size: 42 KiB |
143
Godeps/_workspace/src/github.com/gizak/termui/example/theme.go
generated
vendored
|
|
@ -1,143 +0,0 @@
|
||||||
// Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved.
|
|
||||||
// Use of this source code is governed by a MIT license that can
|
|
||||||
// be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import ui "github.com/gizak/termui"
|
|
||||||
import "math"
|
|
||||||
|
|
||||||
import "time"
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
err := ui.Init()
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
defer ui.Close()
|
|
||||||
|
|
||||||
ui.UseTheme("helloworld")
|
|
||||||
|
|
||||||
p := ui.NewPar(":PRESS q TO QUIT DEMO")
|
|
||||||
p.Height = 3
|
|
||||||
p.Width = 50
|
|
||||||
p.Border.Label = "Text Box"
|
|
||||||
|
|
||||||
strs := []string{"[0] gizak/termui", "[1] editbox.go", "[2] iterrupt.go", "[3] keyboard.go", "[4] output.go", "[5] random_out.go", "[6] dashboard.go", "[7] nsf/termbox-go"}
|
|
||||||
list := ui.NewList()
|
|
||||||
list.Items = strs
|
|
||||||
list.Border.Label = "List"
|
|
||||||
list.Height = 7
|
|
||||||
list.Width = 25
|
|
||||||
list.Y = 4
|
|
||||||
|
|
||||||
g := ui.NewGauge()
|
|
||||||
g.Percent = 50
|
|
||||||
g.Width = 50
|
|
||||||
g.Height = 3
|
|
||||||
g.Y = 11
|
|
||||||
g.Border.Label = "Gauge"
|
|
||||||
|
|
||||||
spark := ui.NewSparkline()
|
|
||||||
spark.Title = "srv 0:"
|
|
||||||
spdata := []int{4, 2, 1, 6, 3, 9, 1, 4, 2, 15, 14, 9, 8, 6, 10, 13, 15, 12, 10, 5, 3, 6, 1, 7, 10, 10, 14, 13, 6}
|
|
||||||
spark.Data = spdata
|
|
||||||
|
|
||||||
spark1 := ui.NewSparkline()
|
|
||||||
spark1.Title = "srv 1:"
|
|
||||||
spark1.Data = spdata
|
|
||||||
|
|
||||||
sp := ui.NewSparklines(spark, spark1)
|
|
||||||
sp.Width = 25
|
|
||||||
sp.Height = 7
|
|
||||||
sp.Border.Label = "Sparkline"
|
|
||||||
sp.Y = 4
|
|
||||||
sp.X = 25
|
|
||||||
|
|
||||||
lc := ui.NewLineChart()
|
|
||||||
sinps := (func() []float64 {
|
|
||||||
n := 100
|
|
||||||
ps := make([]float64, n)
|
|
||||||
for i := range ps {
|
|
||||||
ps[i] = 1 + math.Sin(float64(i)/4)
|
|
||||||
}
|
|
||||||
return ps
|
|
||||||
})()
|
|
||||||
|
|
||||||
lc.Border.Label = "Line Chart"
|
|
||||||
lc.Data = sinps
|
|
||||||
lc.Width = 50
|
|
||||||
lc.Height = 11
|
|
||||||
lc.X = 0
|
|
||||||
lc.Y = 14
|
|
||||||
lc.Mode = "dot"
|
|
||||||
|
|
||||||
bc := ui.NewBarChart()
|
|
||||||
bcdata := []int{3, 2, 5, 3, 9, 5, 3, 2, 5, 8, 3, 2, 4, 5, 3, 2, 5, 7, 5, 3, 2, 6, 7, 4, 6, 3, 6, 7, 8, 3, 6, 4, 5, 3, 2, 4, 6, 4, 8, 5, 9, 4, 3, 6, 5, 3, 6}
|
|
||||||
bclabels := []string{"S0", "S1", "S2", "S3", "S4", "S5"}
|
|
||||||
bc.Border.Label = "Bar Chart"
|
|
||||||
bc.Width = 26
|
|
||||||
bc.Height = 10
|
|
||||||
bc.X = 51
|
|
||||||
bc.Y = 0
|
|
||||||
bc.DataLabels = bclabels
|
|
||||||
|
|
||||||
lc1 := ui.NewLineChart()
|
|
||||||
lc1.Border.Label = "Line Chart"
|
|
||||||
rndwalk := (func() []float64 {
|
|
||||||
n := 150
|
|
||||||
d := make([]float64, n)
|
|
||||||
for i := 1; i < n; i++ {
|
|
||||||
if i < 20 {
|
|
||||||
d[i] = d[i-1] + 0.01
|
|
||||||
}
|
|
||||||
if i > 20 {
|
|
||||||
d[i] = d[i-1] - 0.05
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return d
|
|
||||||
})()
|
|
||||||
lc1.Data = rndwalk
|
|
||||||
lc1.Width = 26
|
|
||||||
lc1.Height = 11
|
|
||||||
lc1.X = 51
|
|
||||||
lc1.Y = 14
|
|
||||||
|
|
||||||
p1 := ui.NewPar("Hey!\nI am a borderless block!")
|
|
||||||
p1.HasBorder = false
|
|
||||||
p1.Width = 26
|
|
||||||
p1.Height = 2
|
|
||||||
p1.X = 52
|
|
||||||
p1.Y = 11
|
|
||||||
|
|
||||||
draw := func(t int) {
|
|
||||||
g.Percent = t % 101
|
|
||||||
list.Items = strs[t%9:]
|
|
||||||
sp.Lines[0].Data = spdata[t%10:]
|
|
||||||
sp.Lines[1].Data = spdata[t/2%10:]
|
|
||||||
lc.Data = sinps[t/2:]
|
|
||||||
lc1.Data = rndwalk[t:]
|
|
||||||
bc.Data = bcdata[t/2%10:]
|
|
||||||
ui.Render(p, list, g, sp, lc, bc, lc1, p1)
|
|
||||||
}
|
|
||||||
|
|
||||||
evt := ui.EventCh()
|
|
||||||
i := 0
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case e := <-evt:
|
|
||||||
if e.Type == ui.EventKey && e.Ch == 'q' {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
draw(i)
|
|
||||||
i++
|
|
||||||
if i == 102 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
time.Sleep(time.Second / 2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BIN
Godeps/_workspace/src/github.com/gizak/termui/example/themedefault.png
generated
vendored
|
Before Width: | Height: | Size: 103 KiB |
BIN
Godeps/_workspace/src/github.com/gizak/termui/example/themehelloworld.png
generated
vendored
|
Before Width: | Height: | Size: 88 KiB |
96
Godeps/_workspace/src/github.com/gizak/termui/gauge.go
generated
vendored
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved.
|
// Copyright 2016 Zack Guo <gizak@icloud.com>. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license that can
|
// Use of this source code is governed by a MIT license that can
|
||||||
// be found in the LICENSE file.
|
// be found in the LICENSE file.
|
||||||
|
|
||||||
|
|
@ -21,33 +21,27 @@ import (
|
||||||
g.PercentColor = termui.ColorBlue
|
g.PercentColor = termui.ColorBlue
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Align is the position of the gauge's label.
|
const ColorUndef Attribute = Attribute(^uint16(0))
|
||||||
type Align int
|
|
||||||
|
|
||||||
// All supported positions.
|
|
||||||
const (
|
|
||||||
AlignLeft Align = iota
|
|
||||||
AlignCenter
|
|
||||||
AlignRight
|
|
||||||
)
|
|
||||||
|
|
||||||
type Gauge struct {
|
type Gauge struct {
|
||||||
Block
|
Block
|
||||||
Percent int
|
Percent int
|
||||||
BarColor Attribute
|
BarColor Attribute
|
||||||
PercentColor Attribute
|
PercentColor Attribute
|
||||||
Label string
|
PercentColorHighlighted Attribute
|
||||||
LabelAlign Align
|
Label string
|
||||||
|
LabelAlign Align
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewGauge return a new gauge with current theme.
|
// NewGauge return a new gauge with current theme.
|
||||||
func NewGauge() *Gauge {
|
func NewGauge() *Gauge {
|
||||||
g := &Gauge{
|
g := &Gauge{
|
||||||
Block: *NewBlock(),
|
Block: *NewBlock(),
|
||||||
PercentColor: theme.GaugePercent,
|
PercentColor: ThemeAttr("gauge.percent.fg"),
|
||||||
BarColor: theme.GaugeBar,
|
BarColor: ThemeAttr("gauge.bar.bg"),
|
||||||
Label: "{{percent}}%",
|
Label: "{{percent}}%",
|
||||||
LabelAlign: AlignCenter,
|
LabelAlign: AlignCenter,
|
||||||
|
PercentColorHighlighted: ColorUndef,
|
||||||
}
|
}
|
||||||
|
|
||||||
g.Width = 12
|
g.Width = 12
|
||||||
|
|
@ -56,28 +50,26 @@ func NewGauge() *Gauge {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Buffer implements Bufferer interface.
|
// Buffer implements Bufferer interface.
|
||||||
func (g *Gauge) Buffer() []Point {
|
func (g *Gauge) Buffer() Buffer {
|
||||||
ps := g.Block.Buffer()
|
buf := g.Block.Buffer()
|
||||||
|
|
||||||
// plot bar
|
// plot bar
|
||||||
w := g.Percent * g.innerWidth / 100
|
w := g.Percent * g.innerArea.Dx() / 100
|
||||||
for i := 0; i < g.innerHeight; i++ {
|
for i := 0; i < g.innerArea.Dy(); i++ {
|
||||||
for j := 0; j < w; j++ {
|
for j := 0; j < w; j++ {
|
||||||
p := Point{}
|
c := Cell{}
|
||||||
p.X = g.innerX + j
|
c.Ch = ' '
|
||||||
p.Y = g.innerY + i
|
c.Bg = g.BarColor
|
||||||
p.Ch = ' '
|
if c.Bg == ColorDefault {
|
||||||
p.Bg = g.BarColor
|
c.Bg |= AttrReverse
|
||||||
if p.Bg == ColorDefault {
|
|
||||||
p.Bg |= AttrReverse
|
|
||||||
}
|
}
|
||||||
ps = append(ps, p)
|
buf.Set(g.innerArea.Min.X+j, g.innerArea.Min.Y+i, c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// plot percentage
|
// plot percentage
|
||||||
s := strings.Replace(g.Label, "{{percent}}", strconv.Itoa(g.Percent), -1)
|
s := strings.Replace(g.Label, "{{percent}}", strconv.Itoa(g.Percent), -1)
|
||||||
pry := g.innerY + g.innerHeight/2
|
pry := g.innerArea.Min.Y + g.innerArea.Dy()/2
|
||||||
rs := str2runes(s)
|
rs := str2runes(s)
|
||||||
var pos int
|
var pos int
|
||||||
switch g.LabelAlign {
|
switch g.LabelAlign {
|
||||||
|
|
@ -85,29 +77,33 @@ func (g *Gauge) Buffer() []Point {
|
||||||
pos = 0
|
pos = 0
|
||||||
|
|
||||||
case AlignCenter:
|
case AlignCenter:
|
||||||
pos = (g.innerWidth - strWidth(s)) / 2
|
pos = (g.innerArea.Dx() - strWidth(s)) / 2
|
||||||
|
|
||||||
case AlignRight:
|
case AlignRight:
|
||||||
pos = g.innerWidth - strWidth(s)
|
pos = g.innerArea.Dx() - strWidth(s) - 1
|
||||||
}
|
}
|
||||||
|
pos += g.innerArea.Min.X
|
||||||
|
|
||||||
for i, v := range rs {
|
for i, v := range rs {
|
||||||
p := Point{}
|
c := Cell{
|
||||||
p.X = 1 + pos + i
|
Ch: v,
|
||||||
p.Y = pry
|
Fg: g.PercentColor,
|
||||||
p.Ch = v
|
|
||||||
p.Fg = g.PercentColor
|
|
||||||
if w+g.innerX > pos+i {
|
|
||||||
p.Bg = g.BarColor
|
|
||||||
if p.Bg == ColorDefault {
|
|
||||||
p.Bg |= AttrReverse
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
p.Bg = g.Block.BgColor
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ps = append(ps, p)
|
if w+g.innerArea.Min.X > pos+i {
|
||||||
|
c.Bg = g.BarColor
|
||||||
|
if c.Bg == ColorDefault {
|
||||||
|
c.Bg |= AttrReverse
|
||||||
|
}
|
||||||
|
|
||||||
|
if g.PercentColorHighlighted != ColorUndef {
|
||||||
|
c.Fg = g.PercentColorHighlighted
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
c.Bg = g.Block.Bg
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.Set(1+pos+i, pry, c)
|
||||||
}
|
}
|
||||||
return g.Block.chopOverflow(ps)
|
return buf
|
||||||
}
|
}
|
||||||
|
|
|
||||||
20
Godeps/_workspace/src/github.com/gizak/termui/grid.go
generated
vendored
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved.
|
// Copyright 2016 Zack Guo <gizak@icloud.com>. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license that can
|
// Use of this source code is governed by a MIT license that can
|
||||||
// be found in the LICENSE file.
|
// be found in the LICENSE file.
|
||||||
|
|
||||||
|
|
@ -160,8 +160,8 @@ func (r *Row) SetWidth(w int) {
|
||||||
|
|
||||||
// Buffer implements Bufferer interface,
|
// Buffer implements Bufferer interface,
|
||||||
// recursively merge all widgets buffer
|
// recursively merge all widgets buffer
|
||||||
func (r *Row) Buffer() []Point {
|
func (r *Row) Buffer() Buffer {
|
||||||
merged := []Point{}
|
merged := NewBuffer()
|
||||||
|
|
||||||
if r.isRenderableLeaf() {
|
if r.isRenderableLeaf() {
|
||||||
return r.Widget.Buffer()
|
return r.Widget.Buffer()
|
||||||
|
|
@ -169,13 +169,13 @@ func (r *Row) Buffer() []Point {
|
||||||
|
|
||||||
// for those are not leaves but have a renderable widget
|
// for those are not leaves but have a renderable widget
|
||||||
if r.Widget != nil {
|
if r.Widget != nil {
|
||||||
merged = append(merged, r.Widget.Buffer()...)
|
merged.Merge(r.Widget.Buffer())
|
||||||
}
|
}
|
||||||
|
|
||||||
// collect buffer from children
|
// collect buffer from children
|
||||||
if !r.isLeaf() {
|
if !r.isLeaf() {
|
||||||
for _, c := range r.Cols {
|
for _, c := range r.Cols {
|
||||||
merged = append(merged, c.Buffer()...)
|
merged.Merge(c.Buffer())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -267,13 +267,13 @@ func (g *Grid) Align() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Buffer implments Bufferer interface.
|
// Buffer implments Bufferer interface.
|
||||||
func (g Grid) Buffer() []Point {
|
func (g Grid) Buffer() Buffer {
|
||||||
ps := []Point{}
|
buf := NewBuffer()
|
||||||
|
|
||||||
for _, r := range g.Rows {
|
for _, r := range g.Rows {
|
||||||
ps = append(ps, r.Buffer()...)
|
buf.Merge(r.Buffer())
|
||||||
}
|
}
|
||||||
return ps
|
return buf
|
||||||
}
|
}
|
||||||
|
|
||||||
// Body corresponds to the entire terminal display region.
|
|
||||||
var Body *Grid
|
var Body *Grid
|
||||||
|
|
|
||||||
98
Godeps/_workspace/src/github.com/gizak/termui/grid_test.go
generated
vendored
|
|
@ -1,98 +0,0 @@
|
||||||
// Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved.
|
|
||||||
// Use of this source code is governed by a MIT license that can
|
|
||||||
// be found in the LICENSE file.
|
|
||||||
|
|
||||||
package termui
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
)
|
|
||||||
|
|
||||||
var r *Row
|
|
||||||
|
|
||||||
func TestRowWidth(t *testing.T) {
|
|
||||||
p0 := NewPar("p0")
|
|
||||||
p0.Height = 1
|
|
||||||
p1 := NewPar("p1")
|
|
||||||
p1.Height = 1
|
|
||||||
p2 := NewPar("p2")
|
|
||||||
p2.Height = 1
|
|
||||||
p3 := NewPar("p3")
|
|
||||||
p3.Height = 1
|
|
||||||
|
|
||||||
/* test against tree:
|
|
||||||
|
|
||||||
r
|
|
||||||
/ \
|
|
||||||
0:w 1
|
|
||||||
/ \
|
|
||||||
10:w 11
|
|
||||||
/
|
|
||||||
110:w
|
|
||||||
/
|
|
||||||
1100:w
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
r = &row{
|
|
||||||
Span: 12,
|
|
||||||
Cols: []*row{
|
|
||||||
&row{Widget: p0, Span: 6},
|
|
||||||
&row{
|
|
||||||
Span: 6,
|
|
||||||
Cols: []*row{
|
|
||||||
&row{Widget: p1, Span: 6},
|
|
||||||
&row{
|
|
||||||
Span: 6,
|
|
||||||
Cols: []*row{
|
|
||||||
&row{
|
|
||||||
Span: 12,
|
|
||||||
Widget: p2,
|
|
||||||
Cols: []*row{
|
|
||||||
&row{Span: 12, Widget: p3}}}}}}}}}
|
|
||||||
*/
|
|
||||||
|
|
||||||
r = NewRow(
|
|
||||||
NewCol(6, 0, p0),
|
|
||||||
NewCol(6, 0,
|
|
||||||
NewRow(
|
|
||||||
NewCol(6, 0, p1),
|
|
||||||
NewCol(6, 0, p2, p3))))
|
|
||||||
|
|
||||||
r.assignWidth(100)
|
|
||||||
if r.Width != 100 ||
|
|
||||||
(r.Cols[0].Width) != 50 ||
|
|
||||||
(r.Cols[1].Width) != 50 ||
|
|
||||||
(r.Cols[1].Cols[0].Width) != 25 ||
|
|
||||||
(r.Cols[1].Cols[1].Width) != 25 ||
|
|
||||||
(r.Cols[1].Cols[1].Cols[0].Width) != 25 ||
|
|
||||||
(r.Cols[1].Cols[1].Cols[0].Cols[0].Width) != 25 {
|
|
||||||
t.Error("assignWidth fails")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestRowHeight(t *testing.T) {
|
|
||||||
spew.Dump()
|
|
||||||
|
|
||||||
if (r.solveHeight()) != 2 ||
|
|
||||||
(r.Cols[1].Cols[1].Height) != 2 ||
|
|
||||||
(r.Cols[1].Cols[1].Cols[0].Height) != 2 ||
|
|
||||||
(r.Cols[1].Cols[0].Height) != 1 {
|
|
||||||
t.Error("solveHeight fails")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAssignXY(t *testing.T) {
|
|
||||||
r.assignX(0)
|
|
||||||
r.assignY(0)
|
|
||||||
if (r.Cols[0].X) != 0 ||
|
|
||||||
(r.Cols[1].Cols[0].X) != 50 ||
|
|
||||||
(r.Cols[1].Cols[1].X) != 75 ||
|
|
||||||
(r.Cols[1].Cols[1].Cols[0].X) != 75 ||
|
|
||||||
(r.Cols[1].Cols[0].Y) != 0 ||
|
|
||||||
(r.Cols[1].Cols[1].Cols[0].Y) != 0 ||
|
|
||||||
(r.Cols[1].Cols[1].Cols[0].Cols[0].Y) != 1 {
|
|
||||||
t.Error("assignXY fails")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
156
Godeps/_workspace/src/github.com/gizak/termui/helper.go
generated
vendored
|
|
@ -1,10 +1,15 @@
|
||||||
// Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved.
|
// Copyright 2016 Zack Guo <gizak@icloud.com>. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license that can
|
// Use of this source code is governed by a MIT license that can
|
||||||
// be found in the LICENSE file.
|
// be found in the LICENSE file.
|
||||||
|
|
||||||
package termui
|
package termui
|
||||||
|
|
||||||
import tm "github.com/nsf/termbox-go"
|
import (
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
tm "github.com/nsf/termbox-go"
|
||||||
|
)
|
||||||
import rw "github.com/mattn/go-runewidth"
|
import rw "github.com/mattn/go-runewidth"
|
||||||
|
|
||||||
/* ---------------Port from termbox-go --------------------- */
|
/* ---------------Port from termbox-go --------------------- */
|
||||||
|
|
@ -12,6 +17,7 @@ import rw "github.com/mattn/go-runewidth"
|
||||||
// Attribute is printable cell's color and style.
|
// Attribute is printable cell's color and style.
|
||||||
type Attribute uint16
|
type Attribute uint16
|
||||||
|
|
||||||
|
// 8 basic clolrs
|
||||||
const (
|
const (
|
||||||
ColorDefault Attribute = iota
|
ColorDefault Attribute = iota
|
||||||
ColorBlack
|
ColorBlack
|
||||||
|
|
@ -24,7 +30,10 @@ const (
|
||||||
ColorWhite
|
ColorWhite
|
||||||
)
|
)
|
||||||
|
|
||||||
const NumberofColors = 8 //Have a constant that defines number of colors
|
//Have a constant that defines number of colors
|
||||||
|
const NumberofColors = 8
|
||||||
|
|
||||||
|
// Text style
|
||||||
const (
|
const (
|
||||||
AttrBold Attribute = 1 << (iota + 9)
|
AttrBold Attribute = 1 << (iota + 9)
|
||||||
AttrUnderline
|
AttrUnderline
|
||||||
|
|
@ -46,15 +55,39 @@ func str2runes(s string) []rune {
|
||||||
return []rune(s)
|
return []rune(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Here for backwards-compatibility.
|
||||||
func trimStr2Runes(s string, w int) []rune {
|
func trimStr2Runes(s string, w int) []rune {
|
||||||
|
return TrimStr2Runes(s, w)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TrimStr2Runes trims string to w[-1 rune], appends …, and returns the runes
|
||||||
|
// of that string if string is grather then n. If string is small then w,
|
||||||
|
// return the runes.
|
||||||
|
func TrimStr2Runes(s string, w int) []rune {
|
||||||
if w <= 0 {
|
if w <= 0 {
|
||||||
return []rune{}
|
return []rune{}
|
||||||
}
|
}
|
||||||
|
|
||||||
sw := rw.StringWidth(s)
|
sw := rw.StringWidth(s)
|
||||||
if sw > w {
|
if sw > w {
|
||||||
return []rune(rw.Truncate(s, w, dot))
|
return []rune(rw.Truncate(s, w, dot))
|
||||||
}
|
}
|
||||||
return str2runes(s) //[]rune(rw.Truncate(s, w, ""))
|
return str2runes(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TrimStrIfAppropriate trim string to "s[:-1] + …"
|
||||||
|
// if string > width otherwise return string
|
||||||
|
func TrimStrIfAppropriate(s string, w int) string {
|
||||||
|
if w <= 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
sw := rw.StringWidth(s)
|
||||||
|
if sw > w {
|
||||||
|
return rw.Truncate(s, w, dot)
|
||||||
|
}
|
||||||
|
|
||||||
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
func strWidth(s string) int {
|
func strWidth(s string) int {
|
||||||
|
|
@ -64,3 +97,118 @@ func strWidth(s string) int {
|
||||||
func charWidth(ch rune) int {
|
func charWidth(ch rune) int {
|
||||||
return rw.RuneWidth(ch)
|
return rw.RuneWidth(ch)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var whiteSpaceRegex = regexp.MustCompile(`\s`)
|
||||||
|
|
||||||
|
// StringToAttribute converts text to a termui attribute. You may specifiy more
|
||||||
|
// then one attribute like that: "BLACK, BOLD, ...". All whitespaces
|
||||||
|
// are ignored.
|
||||||
|
func StringToAttribute(text string) Attribute {
|
||||||
|
text = whiteSpaceRegex.ReplaceAllString(strings.ToLower(text), "")
|
||||||
|
attributes := strings.Split(text, ",")
|
||||||
|
result := Attribute(0)
|
||||||
|
|
||||||
|
for _, theAttribute := range attributes {
|
||||||
|
var match Attribute
|
||||||
|
switch theAttribute {
|
||||||
|
case "reset", "default":
|
||||||
|
match = ColorDefault
|
||||||
|
|
||||||
|
case "black":
|
||||||
|
match = ColorBlack
|
||||||
|
|
||||||
|
case "red":
|
||||||
|
match = ColorRed
|
||||||
|
|
||||||
|
case "green":
|
||||||
|
match = ColorGreen
|
||||||
|
|
||||||
|
case "yellow":
|
||||||
|
match = ColorYellow
|
||||||
|
|
||||||
|
case "blue":
|
||||||
|
match = ColorBlue
|
||||||
|
|
||||||
|
case "magenta":
|
||||||
|
match = ColorMagenta
|
||||||
|
|
||||||
|
case "cyan":
|
||||||
|
match = ColorCyan
|
||||||
|
|
||||||
|
case "white":
|
||||||
|
match = ColorWhite
|
||||||
|
|
||||||
|
case "bold":
|
||||||
|
match = AttrBold
|
||||||
|
|
||||||
|
case "underline":
|
||||||
|
match = AttrUnderline
|
||||||
|
|
||||||
|
case "reverse":
|
||||||
|
match = AttrReverse
|
||||||
|
}
|
||||||
|
|
||||||
|
result |= match
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// TextCells returns a coloured text cells []Cell
|
||||||
|
func TextCells(s string, fg, bg Attribute) []Cell {
|
||||||
|
cs := make([]Cell, 0, len(s))
|
||||||
|
|
||||||
|
// sequence := MarkdownTextRendererFactory{}.TextRenderer(s).Render(fg, bg)
|
||||||
|
// runes := []rune(sequence.NormalizedText)
|
||||||
|
runes := str2runes(s)
|
||||||
|
|
||||||
|
for n := range runes {
|
||||||
|
// point, _ := sequence.PointAt(n, 0, 0)
|
||||||
|
// cs = append(cs, Cell{point.Ch, point.Fg, point.Bg})
|
||||||
|
cs = append(cs, Cell{runes[n], fg, bg})
|
||||||
|
}
|
||||||
|
return cs
|
||||||
|
}
|
||||||
|
|
||||||
|
// Width returns the actual screen space the cell takes (usually 1 or 2).
|
||||||
|
func (c Cell) Width() int {
|
||||||
|
return charWidth(c.Ch)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy return a copy of c
|
||||||
|
func (c Cell) Copy() Cell {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// TrimTxCells trims the overflowed text cells sequence.
|
||||||
|
func TrimTxCells(cs []Cell, w int) []Cell {
|
||||||
|
if len(cs) <= w {
|
||||||
|
return cs
|
||||||
|
}
|
||||||
|
return cs[:w]
|
||||||
|
}
|
||||||
|
|
||||||
|
// DTrimTxCls trims the overflowed text cells sequence and append dots at the end.
|
||||||
|
func DTrimTxCls(cs []Cell, w int) []Cell {
|
||||||
|
l := len(cs)
|
||||||
|
if l <= 0 {
|
||||||
|
return []Cell{}
|
||||||
|
}
|
||||||
|
|
||||||
|
rt := make([]Cell, 0, w)
|
||||||
|
csw := 0
|
||||||
|
for i := 0; i < l && csw <= w; i++ {
|
||||||
|
c := cs[i]
|
||||||
|
cw := c.Width()
|
||||||
|
|
||||||
|
if cw+csw < w {
|
||||||
|
rt = append(rt, c)
|
||||||
|
csw += cw
|
||||||
|
} else {
|
||||||
|
rt = append(rt, Cell{'…', c.Fg, c.Bg})
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rt
|
||||||
|
}
|
||||||
|
|
|
||||||
58
Godeps/_workspace/src/github.com/gizak/termui/helper_test.go
generated
vendored
|
|
@ -1,58 +0,0 @@
|
||||||
// Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved.
|
|
||||||
// Use of this source code is governed by a MIT license that can
|
|
||||||
// be found in the LICENSE file.
|
|
||||||
|
|
||||||
package termui
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestStr2Rune(t *testing.T) {
|
|
||||||
s := "你好,世界."
|
|
||||||
rs := str2runes(s)
|
|
||||||
if len(rs) != 6 {
|
|
||||||
t.Error()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestWidth(t *testing.T) {
|
|
||||||
s0 := "つのだ☆HIRO"
|
|
||||||
s1 := "11111111111"
|
|
||||||
spew.Dump(s0)
|
|
||||||
spew.Dump(s1)
|
|
||||||
// above not align for setting East Asian Ambiguous to wide!!
|
|
||||||
|
|
||||||
if strWidth(s0) != strWidth(s1) {
|
|
||||||
t.Error("str len failed")
|
|
||||||
}
|
|
||||||
|
|
||||||
len1 := []rune{'a', '2', '&', '「', 'オ', '。'} //will false: 'ᆵ', 'ᄚ', 'ᄒ'
|
|
||||||
for _, v := range len1 {
|
|
||||||
if charWidth(v) != 1 {
|
|
||||||
t.Error("len1 failed")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
len2 := []rune{'漢', '字', '한', '자', '你', '好', 'だ', '。', '%', 's', 'E', 'ョ', '、', 'ヲ'}
|
|
||||||
for _, v := range len2 {
|
|
||||||
if charWidth(v) != 2 {
|
|
||||||
t.Error("len2 failed")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTrim(t *testing.T) {
|
|
||||||
s := "つのだ☆HIRO"
|
|
||||||
if string(trimStr2Runes(s, 10)) != "つのだ☆HI"+dot {
|
|
||||||
t.Error("trim failed")
|
|
||||||
}
|
|
||||||
if string(trimStr2Runes(s, 11)) != "つのだ☆HIRO" {
|
|
||||||
t.Error("avoid tail trim failed")
|
|
||||||
}
|
|
||||||
if string(trimStr2Runes(s, 15)) != "つのだ☆HIRO" {
|
|
||||||
t.Error("avoid trim failed")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved.
|
// Copyright 2016 Zack Guo <gizak@icloud.com>. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license that can
|
// Use of this source code is governed by a MIT license that can
|
||||||
// be found in the LICENSE file.
|
// be found in the LICENSE file.
|
||||||
|
|
||||||
|
|
@ -74,8 +74,8 @@ type LineChart struct {
|
||||||
// NewLineChart returns a new LineChart with current theme.
|
// NewLineChart returns a new LineChart with current theme.
|
||||||
func NewLineChart() *LineChart {
|
func NewLineChart() *LineChart {
|
||||||
lc := &LineChart{Block: *NewBlock()}
|
lc := &LineChart{Block: *NewBlock()}
|
||||||
lc.AxesColor = theme.LineChartAxes
|
lc.AxesColor = ThemeAttr("linechart.axes.fg")
|
||||||
lc.LineColor = theme.LineChartLine
|
lc.LineColor = ThemeAttr("linechart.line.fg")
|
||||||
lc.Mode = "braille"
|
lc.Mode = "braille"
|
||||||
lc.DotStyle = '•'
|
lc.DotStyle = '•'
|
||||||
lc.axisXLebelGap = 2
|
lc.axisXLebelGap = 2
|
||||||
|
|
@ -87,8 +87,8 @@ func NewLineChart() *LineChart {
|
||||||
|
|
||||||
// one cell contains two data points
|
// one cell contains two data points
|
||||||
// so the capicity is 2x as dot-mode
|
// so the capicity is 2x as dot-mode
|
||||||
func (lc *LineChart) renderBraille() []Point {
|
func (lc *LineChart) renderBraille() Buffer {
|
||||||
ps := []Point{}
|
buf := NewBuffer()
|
||||||
|
|
||||||
// return: b -> which cell should the point be in
|
// return: b -> which cell should the point be in
|
||||||
// m -> in the cell, divided into 4 equal height levels, which subcell?
|
// m -> in the cell, divided into 4 equal height levels, which subcell?
|
||||||
|
|
@ -104,44 +104,48 @@ func (lc *LineChart) renderBraille() []Point {
|
||||||
b1, m1 := getPos(lc.Data[2*i+1])
|
b1, m1 := getPos(lc.Data[2*i+1])
|
||||||
|
|
||||||
if b0 == b1 {
|
if b0 == b1 {
|
||||||
p := Point{}
|
c := Cell{
|
||||||
p.Ch = braillePatterns[[2]int{m0, m1}]
|
Ch: braillePatterns[[2]int{m0, m1}],
|
||||||
p.Bg = lc.BgColor
|
Bg: lc.Bg,
|
||||||
p.Fg = lc.LineColor
|
Fg: lc.LineColor,
|
||||||
p.Y = lc.innerY + lc.innerHeight - 3 - b0
|
}
|
||||||
p.X = lc.innerX + lc.labelYSpace + 1 + i
|
y := lc.innerArea.Min.Y + lc.innerArea.Dy() - 3 - b0
|
||||||
ps = append(ps, p)
|
x := lc.innerArea.Min.X + lc.labelYSpace + 1 + i
|
||||||
|
buf.Set(x, y, c)
|
||||||
} else {
|
} else {
|
||||||
p0 := newPointWithAttrs(lSingleBraille[m0],
|
c0 := Cell{Ch: lSingleBraille[m0],
|
||||||
lc.innerX+lc.labelYSpace+1+i,
|
Fg: lc.LineColor,
|
||||||
lc.innerY+lc.innerHeight-3-b0,
|
Bg: lc.Bg}
|
||||||
lc.LineColor,
|
x0 := lc.innerArea.Min.X + lc.labelYSpace + 1 + i
|
||||||
lc.BgColor)
|
y0 := lc.innerArea.Min.Y + lc.innerArea.Dy() - 3 - b0
|
||||||
p1 := newPointWithAttrs(rSingleBraille[m1],
|
buf.Set(x0, y0, c0)
|
||||||
lc.innerX+lc.labelYSpace+1+i,
|
|
||||||
lc.innerY+lc.innerHeight-3-b1,
|
c1 := Cell{Ch: rSingleBraille[m1],
|
||||||
lc.LineColor,
|
Fg: lc.LineColor,
|
||||||
lc.BgColor)
|
Bg: lc.Bg}
|
||||||
ps = append(ps, p0, p1)
|
x1 := lc.innerArea.Min.X + lc.labelYSpace + 1 + i
|
||||||
|
y1 := lc.innerArea.Min.Y + lc.innerArea.Dy() - 3 - b1
|
||||||
|
buf.Set(x1, y1, c1)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return ps
|
return buf
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lc *LineChart) renderDot() []Point {
|
func (lc *LineChart) renderDot() Buffer {
|
||||||
ps := []Point{}
|
buf := NewBuffer()
|
||||||
for i := 0; i < len(lc.Data) && i < lc.axisXWidth; i++ {
|
for i := 0; i < len(lc.Data) && i < lc.axisXWidth; i++ {
|
||||||
p := Point{}
|
c := Cell{
|
||||||
p.Ch = lc.DotStyle
|
Ch: lc.DotStyle,
|
||||||
p.Fg = lc.LineColor
|
Fg: lc.LineColor,
|
||||||
p.Bg = lc.BgColor
|
Bg: lc.Bg,
|
||||||
p.X = lc.innerX + lc.labelYSpace + 1 + i
|
}
|
||||||
p.Y = lc.innerY + lc.innerHeight - 3 - int((lc.Data[i]-lc.bottomValue)/lc.scale+0.5)
|
x := lc.innerArea.Min.X + lc.labelYSpace + 1 + i
|
||||||
ps = append(ps, p)
|
y := lc.innerArea.Min.Y + lc.innerArea.Dy() - 3 - int((lc.Data[i]-lc.bottomValue)/lc.scale+0.5)
|
||||||
|
buf.Set(x, y, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ps
|
return buf
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lc *LineChart) calcLabelX() {
|
func (lc *LineChart) calcLabelX() {
|
||||||
|
|
@ -220,9 +224,9 @@ func (lc *LineChart) calcLayout() {
|
||||||
lc.maxY = lc.Data[0]
|
lc.maxY = lc.Data[0]
|
||||||
|
|
||||||
// valid visible range
|
// valid visible range
|
||||||
vrange := lc.innerWidth
|
vrange := lc.innerArea.Dx()
|
||||||
if lc.Mode == "braille" {
|
if lc.Mode == "braille" {
|
||||||
vrange = 2 * lc.innerWidth
|
vrange = 2 * lc.innerArea.Dx()
|
||||||
}
|
}
|
||||||
if vrange > len(lc.Data) {
|
if vrange > len(lc.Data) {
|
||||||
vrange = len(lc.Data)
|
vrange = len(lc.Data)
|
||||||
|
|
@ -247,40 +251,30 @@ func (lc *LineChart) calcLayout() {
|
||||||
lc.topValue = lc.maxY + 0.2*span
|
lc.topValue = lc.maxY + 0.2*span
|
||||||
}
|
}
|
||||||
|
|
||||||
lc.axisYHeight = lc.innerHeight - 2
|
lc.axisYHeight = lc.innerArea.Dy() - 2
|
||||||
lc.calcLabelY()
|
lc.calcLabelY()
|
||||||
|
|
||||||
lc.axisXWidth = lc.innerWidth - 1 - lc.labelYSpace
|
lc.axisXWidth = lc.innerArea.Dx() - 1 - lc.labelYSpace
|
||||||
lc.calcLabelX()
|
lc.calcLabelX()
|
||||||
|
|
||||||
lc.drawingX = lc.innerX + 1 + lc.labelYSpace
|
lc.drawingX = lc.innerArea.Min.X + 1 + lc.labelYSpace
|
||||||
lc.drawingY = lc.innerY
|
lc.drawingY = lc.innerArea.Min.Y
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lc *LineChart) plotAxes() []Point {
|
func (lc *LineChart) plotAxes() Buffer {
|
||||||
origY := lc.innerY + lc.innerHeight - 2
|
buf := NewBuffer()
|
||||||
origX := lc.innerX + lc.labelYSpace
|
|
||||||
|
|
||||||
ps := []Point{newPointWithAttrs(ORIGIN, origX, origY, lc.AxesColor, lc.BgColor)}
|
origY := lc.innerArea.Min.Y + lc.innerArea.Dy() - 2
|
||||||
|
origX := lc.innerArea.Min.X + lc.labelYSpace
|
||||||
|
|
||||||
|
buf.Set(origX, origY, Cell{Ch: ORIGIN, Fg: lc.AxesColor, Bg: lc.Bg})
|
||||||
|
|
||||||
for x := origX + 1; x < origX+lc.axisXWidth; x++ {
|
for x := origX + 1; x < origX+lc.axisXWidth; x++ {
|
||||||
p := Point{}
|
buf.Set(x, origY, Cell{Ch: HDASH, Fg: lc.AxesColor, Bg: lc.Bg})
|
||||||
p.X = x
|
|
||||||
p.Y = origY
|
|
||||||
p.Bg = lc.BgColor
|
|
||||||
p.Fg = lc.AxesColor
|
|
||||||
p.Ch = HDASH
|
|
||||||
ps = append(ps, p)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for dy := 1; dy <= lc.axisYHeight; dy++ {
|
for dy := 1; dy <= lc.axisYHeight; dy++ {
|
||||||
p := Point{}
|
buf.Set(origX, origY-dy, Cell{Ch: VDASH, Fg: lc.AxesColor, Bg: lc.Bg})
|
||||||
p.X = origX
|
|
||||||
p.Y = origY - dy
|
|
||||||
p.Bg = lc.BgColor
|
|
||||||
p.Fg = lc.AxesColor
|
|
||||||
p.Ch = VDASH
|
|
||||||
ps = append(ps, p)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// x label
|
// x label
|
||||||
|
|
@ -290,13 +284,14 @@ func (lc *LineChart) plotAxes() []Point {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
for j, r := range rs {
|
for j, r := range rs {
|
||||||
p := Point{}
|
c := Cell{
|
||||||
p.Ch = r
|
Ch: r,
|
||||||
p.Fg = lc.AxesColor
|
Fg: lc.AxesColor,
|
||||||
p.Bg = lc.BgColor
|
Bg: lc.Bg,
|
||||||
p.X = origX + oft + j
|
}
|
||||||
p.Y = lc.innerY + lc.innerHeight - 1
|
x := origX + oft + j
|
||||||
ps = append(ps, p)
|
y := lc.innerArea.Min.Y + lc.innerArea.Dy() - 1
|
||||||
|
buf.Set(x, y, c)
|
||||||
}
|
}
|
||||||
oft += len(rs) + lc.axisXLebelGap
|
oft += len(rs) + lc.axisXLebelGap
|
||||||
}
|
}
|
||||||
|
|
@ -304,33 +299,31 @@ func (lc *LineChart) plotAxes() []Point {
|
||||||
// y labels
|
// y labels
|
||||||
for i, rs := range lc.labelY {
|
for i, rs := range lc.labelY {
|
||||||
for j, r := range rs {
|
for j, r := range rs {
|
||||||
p := Point{}
|
buf.Set(
|
||||||
p.Ch = r
|
lc.innerArea.Min.X+j,
|
||||||
p.Fg = lc.AxesColor
|
origY-i*(lc.axisYLebelGap+1),
|
||||||
p.Bg = lc.BgColor
|
Cell{Ch: r, Fg: lc.AxesColor, Bg: lc.Bg})
|
||||||
p.X = lc.innerX + j
|
|
||||||
p.Y = origY - i*(lc.axisYLebelGap+1)
|
|
||||||
ps = append(ps, p)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ps
|
return buf
|
||||||
}
|
}
|
||||||
|
|
||||||
// Buffer implements Bufferer interface.
|
// Buffer implements Bufferer interface.
|
||||||
func (lc *LineChart) Buffer() []Point {
|
func (lc *LineChart) Buffer() Buffer {
|
||||||
ps := lc.Block.Buffer()
|
buf := lc.Block.Buffer()
|
||||||
|
|
||||||
if lc.Data == nil || len(lc.Data) == 0 {
|
if lc.Data == nil || len(lc.Data) == 0 {
|
||||||
return ps
|
return buf
|
||||||
}
|
}
|
||||||
lc.calcLayout()
|
lc.calcLayout()
|
||||||
ps = append(ps, lc.plotAxes()...)
|
buf.Merge(lc.plotAxes())
|
||||||
|
|
||||||
if lc.Mode == "dot" {
|
if lc.Mode == "dot" {
|
||||||
ps = append(ps, lc.renderDot()...)
|
buf.Merge(lc.renderDot())
|
||||||
} else {
|
} else {
|
||||||
ps = append(ps, lc.renderBraille()...)
|
buf.Merge(lc.renderBraille())
|
||||||
}
|
}
|
||||||
|
|
||||||
return lc.Block.chopOverflow(ps)
|
return buf
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved.
|
// Copyright 2016 Zack Guo <gizak@icloud.com>. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license that can
|
// Use of this source code is governed by a MIT license that can
|
||||||
// be found in the LICENSE file.
|
// be found in the LICENSE file.
|
||||||
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved.
|
// Copyright 2016 Zack Guo <gizak@icloud.com>. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license that can
|
// Use of this source code is governed by a MIT license that can
|
||||||
// be found in the LICENSE file.
|
// be found in the LICENSE file.
|
||||||
|
|
||||||
53
Godeps/_workspace/src/github.com/gizak/termui/list.go
generated
vendored
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved.
|
// Copyright 2016 Zack Guo <gizak@icloud.com>. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license that can
|
// Use of this source code is governed by a MIT license that can
|
||||||
// be found in the LICENSE file.
|
// be found in the LICENSE file.
|
||||||
|
|
||||||
|
|
@ -41,64 +41,49 @@ type List struct {
|
||||||
func NewList() *List {
|
func NewList() *List {
|
||||||
l := &List{Block: *NewBlock()}
|
l := &List{Block: *NewBlock()}
|
||||||
l.Overflow = "hidden"
|
l.Overflow = "hidden"
|
||||||
l.ItemFgColor = theme.ListItemFg
|
l.ItemFgColor = ThemeAttr("list.item.fg")
|
||||||
l.ItemBgColor = theme.ListItemBg
|
l.ItemBgColor = ThemeAttr("list.item.bg")
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
|
||||||
// Buffer implements Bufferer interface.
|
// Buffer implements Bufferer interface.
|
||||||
func (l *List) Buffer() []Point {
|
func (l *List) Buffer() Buffer {
|
||||||
ps := l.Block.Buffer()
|
buf := l.Block.Buffer()
|
||||||
|
|
||||||
switch l.Overflow {
|
switch l.Overflow {
|
||||||
case "wrap":
|
case "wrap":
|
||||||
rs := str2runes(strings.Join(l.Items, "\n"))
|
cs := DefaultTxBuilder.Build(strings.Join(l.Items, "\n"), l.ItemFgColor, l.ItemBgColor)
|
||||||
i, j, k := 0, 0, 0
|
i, j, k := 0, 0, 0
|
||||||
for i < l.innerHeight && k < len(rs) {
|
for i < l.innerArea.Dy() && k < len(cs) {
|
||||||
w := charWidth(rs[k])
|
w := cs[k].Width()
|
||||||
if rs[k] == '\n' || j+w > l.innerWidth {
|
if cs[k].Ch == '\n' || j+w > l.innerArea.Dx() {
|
||||||
i++
|
i++
|
||||||
j = 0
|
j = 0
|
||||||
if rs[k] == '\n' {
|
if cs[k].Ch == '\n' {
|
||||||
k++
|
k++
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
pi := Point{}
|
buf.Set(l.innerArea.Min.X+j, l.innerArea.Min.Y+i, cs[k])
|
||||||
pi.X = l.innerX + j
|
|
||||||
pi.Y = l.innerY + i
|
|
||||||
|
|
||||||
pi.Ch = rs[k]
|
|
||||||
pi.Bg = l.ItemBgColor
|
|
||||||
pi.Fg = l.ItemFgColor
|
|
||||||
|
|
||||||
ps = append(ps, pi)
|
|
||||||
k++
|
k++
|
||||||
j++
|
j++
|
||||||
}
|
}
|
||||||
|
|
||||||
case "hidden":
|
case "hidden":
|
||||||
trimItems := l.Items
|
trimItems := l.Items
|
||||||
if len(trimItems) > l.innerHeight {
|
if len(trimItems) > l.innerArea.Dy() {
|
||||||
trimItems = trimItems[:l.innerHeight]
|
trimItems = trimItems[:l.innerArea.Dy()]
|
||||||
}
|
}
|
||||||
for i, v := range trimItems {
|
for i, v := range trimItems {
|
||||||
rs := trimStr2Runes(v, l.innerWidth)
|
cs := DTrimTxCls(DefaultTxBuilder.Build(v, l.ItemFgColor, l.ItemBgColor), l.innerArea.Dx())
|
||||||
|
|
||||||
j := 0
|
j := 0
|
||||||
for _, vv := range rs {
|
for _, vv := range cs {
|
||||||
w := charWidth(vv)
|
w := vv.Width()
|
||||||
p := Point{}
|
buf.Set(l.innerArea.Min.X+j, l.innerArea.Min.Y+i, vv)
|
||||||
p.X = l.innerX + j
|
|
||||||
p.Y = l.innerY + i
|
|
||||||
|
|
||||||
p.Ch = vv
|
|
||||||
p.Bg = l.ItemBgColor
|
|
||||||
p.Fg = l.ItemFgColor
|
|
||||||
|
|
||||||
ps = append(ps, p)
|
|
||||||
j += w
|
j += w
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return l.Block.chopOverflow(ps)
|
return buf
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved.
|
// Copyright 2016 Zack Guo <gizak@icloud.com>. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license that can
|
// Use of this source code is governed by a MIT license that can
|
||||||
// be found in the LICENSE file.
|
// be found in the LICENSE file.
|
||||||
|
|
||||||
|
|
@ -48,16 +48,16 @@ type MBarChart struct {
|
||||||
// NewBarChart returns a new *BarChart with current theme.
|
// NewBarChart returns a new *BarChart with current theme.
|
||||||
func NewMBarChart() *MBarChart {
|
func NewMBarChart() *MBarChart {
|
||||||
bc := &MBarChart{Block: *NewBlock()}
|
bc := &MBarChart{Block: *NewBlock()}
|
||||||
bc.BarColor[0] = theme.MBarChartBar
|
bc.BarColor[0] = ThemeAttr("mbarchart.bar.bg")
|
||||||
bc.NumColor[0] = theme.MBarChartNum
|
bc.NumColor[0] = ThemeAttr("mbarchart.num.fg")
|
||||||
bc.TextColor = theme.MBarChartText
|
bc.TextColor = ThemeAttr("mbarchart.text.fg")
|
||||||
bc.BarGap = 1
|
bc.BarGap = 1
|
||||||
bc.BarWidth = 3
|
bc.BarWidth = 3
|
||||||
return bc
|
return bc
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bc *MBarChart) layout() {
|
func (bc *MBarChart) layout() {
|
||||||
bc.numBar = bc.innerWidth / (bc.BarGap + bc.BarWidth)
|
bc.numBar = bc.innerArea.Dx() / (bc.BarGap + bc.BarWidth)
|
||||||
bc.labels = make([][]rune, bc.numBar)
|
bc.labels = make([][]rune, bc.numBar)
|
||||||
DataLen := 0
|
DataLen := 0
|
||||||
LabelLen := len(bc.DataLabels)
|
LabelLen := len(bc.DataLabels)
|
||||||
|
|
@ -129,9 +129,9 @@ func (bc *MBarChart) layout() {
|
||||||
if bc.ShowScale {
|
if bc.ShowScale {
|
||||||
s := fmt.Sprintf("%d", bc.max)
|
s := fmt.Sprintf("%d", bc.max)
|
||||||
bc.maxScale = trimStr2Runes(s, len(s))
|
bc.maxScale = trimStr2Runes(s, len(s))
|
||||||
bc.scale = float64(bc.max) / float64(bc.innerHeight-2)
|
bc.scale = float64(bc.max) / float64(bc.innerArea.Dy()-2)
|
||||||
} else {
|
} else {
|
||||||
bc.scale = float64(bc.max) / float64(bc.innerHeight-1)
|
bc.scale = float64(bc.max) / float64(bc.innerArea.Dy()-1)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -144,8 +144,8 @@ func (bc *MBarChart) SetMax(max int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Buffer implements Bufferer interface.
|
// Buffer implements Bufferer interface.
|
||||||
func (bc *MBarChart) Buffer() []Point {
|
func (bc *MBarChart) Buffer() Buffer {
|
||||||
ps := bc.Block.Buffer()
|
buf := bc.Block.Buffer()
|
||||||
bc.layout()
|
bc.layout()
|
||||||
var oftX int
|
var oftX int
|
||||||
|
|
||||||
|
|
@ -157,15 +157,17 @@ func (bc *MBarChart) Buffer() []Point {
|
||||||
// plot bars
|
// plot bars
|
||||||
for j := 0; j < bc.BarWidth; j++ {
|
for j := 0; j < bc.BarWidth; j++ {
|
||||||
for k := 0; k < h; k++ {
|
for k := 0; k < h; k++ {
|
||||||
p := Point{}
|
c := Cell{
|
||||||
p.Ch = ' '
|
Ch: ' ',
|
||||||
p.Bg = bc.BarColor[i1]
|
Bg: bc.BarColor[i1],
|
||||||
if bc.BarColor[i1] == ColorDefault { // when color is default, space char treated as transparent!
|
|
||||||
p.Bg |= AttrReverse
|
|
||||||
}
|
}
|
||||||
p.X = bc.innerX + i*(bc.BarWidth+bc.BarGap) + j
|
if bc.BarColor[i1] == ColorDefault { // when color is default, space char treated as transparent!
|
||||||
p.Y = bc.innerY + bc.innerHeight - 2 - k - ph
|
c.Bg |= AttrReverse
|
||||||
ps = append(ps, p)
|
}
|
||||||
|
x := bc.innerArea.Min.X + i*(bc.BarWidth+bc.BarGap) + j
|
||||||
|
y := bc.innerArea.Min.Y + bc.innerArea.Dy() - 2 - k - ph
|
||||||
|
buf.Set(x, y, c)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ph += h
|
ph += h
|
||||||
|
|
@ -173,13 +175,14 @@ func (bc *MBarChart) Buffer() []Point {
|
||||||
// plot text
|
// plot text
|
||||||
for j, k := 0, 0; j < len(bc.labels[i]); j++ {
|
for j, k := 0, 0; j < len(bc.labels[i]); j++ {
|
||||||
w := charWidth(bc.labels[i][j])
|
w := charWidth(bc.labels[i][j])
|
||||||
p := Point{}
|
c := Cell{
|
||||||
p.Ch = bc.labels[i][j]
|
Ch: bc.labels[i][j],
|
||||||
p.Bg = bc.BgColor
|
Bg: bc.Bg,
|
||||||
p.Fg = bc.TextColor
|
Fg: bc.TextColor,
|
||||||
p.Y = bc.innerY + bc.innerHeight - 1
|
}
|
||||||
p.X = bc.innerX + oftX + ((bc.BarWidth - len(bc.labels[i])) / 2) + k
|
y := bc.innerArea.Min.Y + bc.innerArea.Dy() - 1
|
||||||
ps = append(ps, p)
|
x := bc.innerArea.Max.X + oftX + ((bc.BarWidth - len(bc.labels[i])) / 2) + k
|
||||||
|
buf.Set(x, y, c)
|
||||||
k += w
|
k += w
|
||||||
}
|
}
|
||||||
// plot num
|
// plot num
|
||||||
|
|
@ -187,19 +190,20 @@ func (bc *MBarChart) Buffer() []Point {
|
||||||
for i1 := 0; i1 < bc.numStack; i1++ {
|
for i1 := 0; i1 < bc.numStack; i1++ {
|
||||||
h := int(float64(bc.Data[i1][i]) / bc.scale)
|
h := int(float64(bc.Data[i1][i]) / bc.scale)
|
||||||
for j := 0; j < len(bc.dataNum[i1][i]) && h > 0; j++ {
|
for j := 0; j < len(bc.dataNum[i1][i]) && h > 0; j++ {
|
||||||
p := Point{}
|
c := Cell{
|
||||||
p.Ch = bc.dataNum[i1][i][j]
|
Ch: bc.dataNum[i1][i][j],
|
||||||
p.Fg = bc.NumColor[i1]
|
Fg: bc.NumColor[i1],
|
||||||
p.Bg = bc.BarColor[i1]
|
Bg: bc.BarColor[i1],
|
||||||
|
}
|
||||||
if bc.BarColor[i1] == ColorDefault { // the same as above
|
if bc.BarColor[i1] == ColorDefault { // the same as above
|
||||||
p.Bg |= AttrReverse
|
c.Bg |= AttrReverse
|
||||||
}
|
}
|
||||||
if h == 0 {
|
if h == 0 {
|
||||||
p.Bg = bc.BgColor
|
c.Bg = bc.Bg
|
||||||
}
|
}
|
||||||
p.X = bc.innerX + oftX + (bc.BarWidth-len(bc.dataNum[i1][i]))/2 + j
|
x := bc.innerArea.Min.X + oftX + (bc.BarWidth-len(bc.dataNum[i1][i]))/2 + j
|
||||||
p.Y = bc.innerY + bc.innerHeight - 2 - ph
|
y := bc.innerArea.Min.Y + bc.innerArea.Dy() - 2 - ph
|
||||||
ps = append(ps, p)
|
buf.Set(x, y, c)
|
||||||
}
|
}
|
||||||
ph += h
|
ph += h
|
||||||
}
|
}
|
||||||
|
|
@ -208,26 +212,31 @@ func (bc *MBarChart) Buffer() []Point {
|
||||||
if bc.ShowScale {
|
if bc.ShowScale {
|
||||||
//Currently bar graph only supprts data range from 0 to MAX
|
//Currently bar graph only supprts data range from 0 to MAX
|
||||||
//Plot 0
|
//Plot 0
|
||||||
p := Point{}
|
c := Cell{
|
||||||
p.Ch = '0'
|
Ch: '0',
|
||||||
p.Bg = bc.BgColor
|
Bg: bc.Bg,
|
||||||
p.Fg = bc.TextColor
|
Fg: bc.TextColor,
|
||||||
p.Y = bc.innerY + bc.innerHeight - 2
|
}
|
||||||
p.X = bc.X
|
|
||||||
ps = append(ps, p)
|
y := bc.innerArea.Min.Y + bc.innerArea.Dy() - 2
|
||||||
|
x := bc.X
|
||||||
|
buf.Set(x, y, c)
|
||||||
|
|
||||||
//Plot the maximum sacle value
|
//Plot the maximum sacle value
|
||||||
for i := 0; i < len(bc.maxScale); i++ {
|
for i := 0; i < len(bc.maxScale); i++ {
|
||||||
p := Point{}
|
c := Cell{
|
||||||
p.Ch = bc.maxScale[i]
|
Ch: bc.maxScale[i],
|
||||||
p.Bg = bc.BgColor
|
Bg: bc.Bg,
|
||||||
p.Fg = bc.TextColor
|
Fg: bc.TextColor,
|
||||||
p.Y = bc.innerY
|
}
|
||||||
p.X = bc.X + i
|
|
||||||
ps = append(ps, p)
|
y := bc.innerArea.Min.Y
|
||||||
|
x := bc.X + i
|
||||||
|
|
||||||
|
buf.Set(x, y, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return bc.Block.chopOverflow(ps)
|
return buf
|
||||||
}
|
}
|
||||||
71
Godeps/_workspace/src/github.com/gizak/termui/p.go
generated
vendored
|
|
@ -1,71 +0,0 @@
|
||||||
// Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved.
|
|
||||||
// Use of this source code is governed by a MIT license that can
|
|
||||||
// be found in the LICENSE file.
|
|
||||||
|
|
||||||
package termui
|
|
||||||
|
|
||||||
// Par displays a paragraph.
|
|
||||||
/*
|
|
||||||
par := termui.NewPar("Simple Text")
|
|
||||||
par.Height = 3
|
|
||||||
par.Width = 17
|
|
||||||
par.Border.Label = "Label"
|
|
||||||
*/
|
|
||||||
type Par struct {
|
|
||||||
Block
|
|
||||||
Text string
|
|
||||||
TextFgColor Attribute
|
|
||||||
TextBgColor Attribute
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewPar returns a new *Par with given text as its content.
|
|
||||||
func NewPar(s string) *Par {
|
|
||||||
return &Par{
|
|
||||||
Block: *NewBlock(),
|
|
||||||
Text: s,
|
|
||||||
TextFgColor: theme.ParTextFg,
|
|
||||||
TextBgColor: theme.ParTextBg}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Buffer implements Bufferer interface.
|
|
||||||
func (p *Par) Buffer() []Point {
|
|
||||||
ps := p.Block.Buffer()
|
|
||||||
|
|
||||||
rs := str2runes(p.Text)
|
|
||||||
i, j, k := 0, 0, 0
|
|
||||||
for i < p.innerHeight && k < len(rs) {
|
|
||||||
// the width of char is about to print
|
|
||||||
w := charWidth(rs[k])
|
|
||||||
|
|
||||||
if rs[k] == '\n' || j+w > p.innerWidth {
|
|
||||||
i++
|
|
||||||
j = 0 // set x = 0
|
|
||||||
if rs[k] == '\n' {
|
|
||||||
k++
|
|
||||||
}
|
|
||||||
|
|
||||||
if i >= p.innerHeight {
|
|
||||||
ps = append(ps, newPointWithAttrs('…',
|
|
||||||
p.innerX+p.innerWidth-1,
|
|
||||||
p.innerY+p.innerHeight-1,
|
|
||||||
p.TextFgColor, p.TextBgColor))
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
pi := Point{}
|
|
||||||
pi.X = p.innerX + j
|
|
||||||
pi.Y = p.innerY + i
|
|
||||||
|
|
||||||
pi.Ch = rs[k]
|
|
||||||
pi.Bg = p.TextBgColor
|
|
||||||
pi.Fg = p.TextFgColor
|
|
||||||
|
|
||||||
ps = append(ps, pi)
|
|
||||||
|
|
||||||
k++
|
|
||||||
j += w
|
|
||||||
}
|
|
||||||
return p.Block.chopOverflow(ps)
|
|
||||||
}
|
|
||||||
64
Godeps/_workspace/src/github.com/gizak/termui/par.go
generated
vendored
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
// Copyright 2016 Zack Guo <gizak@icloud.com>. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT license that can
|
||||||
|
// be found in the LICENSE file.
|
||||||
|
|
||||||
|
package termui
|
||||||
|
|
||||||
|
// Par displays a paragraph.
|
||||||
|
/*
|
||||||
|
par := termui.NewPar("Simple Text")
|
||||||
|
par.Height = 3
|
||||||
|
par.Width = 17
|
||||||
|
par.Border.Label = "Label"
|
||||||
|
*/
|
||||||
|
type Par struct {
|
||||||
|
Block
|
||||||
|
Text string
|
||||||
|
TextFgColor Attribute
|
||||||
|
TextBgColor Attribute
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewPar returns a new *Par with given text as its content.
|
||||||
|
func NewPar(s string) *Par {
|
||||||
|
return &Par{
|
||||||
|
Block: *NewBlock(),
|
||||||
|
Text: s,
|
||||||
|
TextFgColor: ThemeAttr("par.text.fg"),
|
||||||
|
TextBgColor: ThemeAttr("par.text.bg"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Buffer implements Bufferer interface.
|
||||||
|
func (p *Par) Buffer() Buffer {
|
||||||
|
buf := p.Block.Buffer()
|
||||||
|
|
||||||
|
fg, bg := p.TextFgColor, p.TextBgColor
|
||||||
|
cs := DefaultTxBuilder.Build(p.Text, fg, bg)
|
||||||
|
|
||||||
|
y, x, n := 0, 0, 0
|
||||||
|
for y < p.innerArea.Dy() && n < len(cs) {
|
||||||
|
w := cs[n].Width()
|
||||||
|
if cs[n].Ch == '\n' || x+w > p.innerArea.Dx() {
|
||||||
|
y++
|
||||||
|
x = 0 // set x = 0
|
||||||
|
if cs[n].Ch == '\n' {
|
||||||
|
n++
|
||||||
|
}
|
||||||
|
|
||||||
|
if y >= p.innerArea.Dy() {
|
||||||
|
buf.Set(p.innerArea.Min.X+p.innerArea.Dx()-1,
|
||||||
|
p.innerArea.Min.Y+p.innerArea.Dy()-1,
|
||||||
|
Cell{Ch: '…', Fg: p.TextFgColor, Bg: p.TextBgColor})
|
||||||
|
break
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.Set(p.innerArea.Min.X+x, p.innerArea.Min.Y+y, cs[n])
|
||||||
|
|
||||||
|
n++
|
||||||
|
x += w
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf
|
||||||
|
}
|
||||||
28
Godeps/_workspace/src/github.com/gizak/termui/point.go
generated
vendored
|
|
@ -1,28 +0,0 @@
|
||||||
// Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved.
|
|
||||||
// Use of this source code is governed by a MIT license that can
|
|
||||||
// be found in the LICENSE file.
|
|
||||||
|
|
||||||
package termui
|
|
||||||
|
|
||||||
// Point stands for a single cell in terminal.
|
|
||||||
type Point struct {
|
|
||||||
Ch rune
|
|
||||||
Bg Attribute
|
|
||||||
Fg Attribute
|
|
||||||
X int
|
|
||||||
Y int
|
|
||||||
}
|
|
||||||
|
|
||||||
func newPoint(c rune, x, y int) (p Point) {
|
|
||||||
p.Ch = c
|
|
||||||
p.X = x
|
|
||||||
p.Y = y
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func newPointWithAttrs(c rune, x, y int, fg, bg Attribute) Point {
|
|
||||||
p := newPoint(c, x, y)
|
|
||||||
p.Bg = bg
|
|
||||||
p.Fg = fg
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
78
Godeps/_workspace/src/github.com/gizak/termui/pos.go
generated
vendored
Normal file
|
|
@ -0,0 +1,78 @@
|
||||||
|
// Copyright 2016 Zack Guo <gizak@icloud.com>. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT license that can
|
||||||
|
// be found in the LICENSE file.
|
||||||
|
|
||||||
|
package termui
|
||||||
|
|
||||||
|
import "image"
|
||||||
|
|
||||||
|
// Align is the position of the gauge's label.
|
||||||
|
type Align uint
|
||||||
|
|
||||||
|
// All supported positions.
|
||||||
|
const (
|
||||||
|
AlignNone Align = 0
|
||||||
|
AlignLeft Align = 1 << iota
|
||||||
|
AlignRight
|
||||||
|
AlignBottom
|
||||||
|
AlignTop
|
||||||
|
AlignCenterVertical
|
||||||
|
AlignCenterHorizontal
|
||||||
|
AlignCenter = AlignCenterVertical | AlignCenterHorizontal
|
||||||
|
)
|
||||||
|
|
||||||
|
func AlignArea(parent, child image.Rectangle, a Align) image.Rectangle {
|
||||||
|
w, h := child.Dx(), child.Dy()
|
||||||
|
|
||||||
|
// parent center
|
||||||
|
pcx, pcy := parent.Min.X+parent.Dx()/2, parent.Min.Y+parent.Dy()/2
|
||||||
|
// child center
|
||||||
|
ccx, ccy := child.Min.X+child.Dx()/2, child.Min.Y+child.Dy()/2
|
||||||
|
|
||||||
|
if a&AlignLeft == AlignLeft {
|
||||||
|
child.Min.X = parent.Min.X
|
||||||
|
child.Max.X = child.Min.X + w
|
||||||
|
}
|
||||||
|
|
||||||
|
if a&AlignRight == AlignRight {
|
||||||
|
child.Max.X = parent.Max.X
|
||||||
|
child.Min.X = child.Max.X - w
|
||||||
|
}
|
||||||
|
|
||||||
|
if a&AlignBottom == AlignBottom {
|
||||||
|
child.Max.Y = parent.Max.Y
|
||||||
|
child.Min.Y = child.Max.Y - h
|
||||||
|
}
|
||||||
|
|
||||||
|
if a&AlignTop == AlignRight {
|
||||||
|
child.Min.Y = parent.Min.Y
|
||||||
|
child.Max.Y = child.Min.Y + h
|
||||||
|
}
|
||||||
|
|
||||||
|
if a&AlignCenterHorizontal == AlignCenterHorizontal {
|
||||||
|
child.Min.X += pcx - ccx
|
||||||
|
child.Max.X = child.Min.X + w
|
||||||
|
}
|
||||||
|
|
||||||
|
if a&AlignCenterVertical == AlignCenterVertical {
|
||||||
|
child.Min.Y += pcy - ccy
|
||||||
|
child.Max.Y = child.Min.Y + h
|
||||||
|
}
|
||||||
|
|
||||||
|
return child
|
||||||
|
}
|
||||||
|
|
||||||
|
func MoveArea(a image.Rectangle, dx, dy int) image.Rectangle {
|
||||||
|
a.Min.X += dx
|
||||||
|
a.Max.X += dx
|
||||||
|
a.Min.Y += dy
|
||||||
|
a.Max.Y += dy
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
var termWidth int
|
||||||
|
var termHeight int
|
||||||
|
|
||||||
|
func TermRect() image.Rectangle {
|
||||||
|
return image.Rect(0, 0, termWidth, termHeight)
|
||||||
|
}
|
||||||
117
Godeps/_workspace/src/github.com/gizak/termui/render.go
generated
vendored
|
|
@ -1,29 +1,62 @@
|
||||||
// Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved.
|
// Copyright 2016 Zack Guo <gizak@icloud.com>. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license that can
|
// Use of this source code is governed by a MIT license that can
|
||||||
// be found in the LICENSE file.
|
// be found in the LICENSE file.
|
||||||
|
|
||||||
package termui
|
package termui
|
||||||
|
|
||||||
import tm "github.com/nsf/termbox-go"
|
import (
|
||||||
|
"image"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
tm "github.com/nsf/termbox-go"
|
||||||
|
)
|
||||||
|
|
||||||
// Bufferer should be implemented by all renderable components.
|
// Bufferer should be implemented by all renderable components.
|
||||||
type Bufferer interface {
|
type Bufferer interface {
|
||||||
Buffer() []Point
|
Buffer() Buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init initializes termui library. This function should be called before any others.
|
// Init initializes termui library. This function should be called before any others.
|
||||||
// After initialization, the library must be finalized by 'Close' function.
|
// After initialization, the library must be finalized by 'Close' function.
|
||||||
func Init() error {
|
func Init() error {
|
||||||
|
if err := tm.Init(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
sysEvtChs = make([]chan Event, 0)
|
||||||
|
go hookTermboxEvt()
|
||||||
|
|
||||||
|
renderJobs = make(chan []Bufferer)
|
||||||
|
//renderLock = new(sync.RWMutex)
|
||||||
|
|
||||||
Body = NewGrid()
|
Body = NewGrid()
|
||||||
Body.X = 0
|
Body.X = 0
|
||||||
Body.Y = 0
|
Body.Y = 0
|
||||||
Body.BgColor = theme.BodyBg
|
Body.BgColor = ThemeAttr("bg")
|
||||||
defer func() {
|
Body.Width = TermWidth()
|
||||||
w, _ := tm.Size()
|
|
||||||
Body.Width = w
|
DefaultEvtStream.Init()
|
||||||
evtListen()
|
DefaultEvtStream.Merge("termbox", NewSysEvtCh())
|
||||||
|
DefaultEvtStream.Merge("timer", NewTimerCh(time.Second))
|
||||||
|
DefaultEvtStream.Merge("custom", usrEvtCh)
|
||||||
|
|
||||||
|
DefaultEvtStream.Handle("/", DefualtHandler)
|
||||||
|
DefaultEvtStream.Handle("/sys/wnd/resize", func(e Event) {
|
||||||
|
w := e.Data.(EvtWnd)
|
||||||
|
Body.Width = w.Width
|
||||||
|
})
|
||||||
|
|
||||||
|
DefaultWgtMgr = NewWgtMgr()
|
||||||
|
DefaultEvtStream.Hook(DefaultWgtMgr.WgtHandlersHook())
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
for bs := range renderJobs {
|
||||||
|
render(bs...)
|
||||||
|
}
|
||||||
}()
|
}()
|
||||||
return tm.Init()
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close finalizes termui library,
|
// Close finalizes termui library,
|
||||||
|
|
@ -32,29 +65,71 @@ func Close() {
|
||||||
tm.Close()
|
tm.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var renderLock sync.Mutex
|
||||||
|
|
||||||
|
func termSync() {
|
||||||
|
renderLock.Lock()
|
||||||
|
tm.Sync()
|
||||||
|
termWidth, termHeight = tm.Size()
|
||||||
|
renderLock.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
// TermWidth returns the current terminal's width.
|
// TermWidth returns the current terminal's width.
|
||||||
func TermWidth() int {
|
func TermWidth() int {
|
||||||
tm.Sync()
|
termSync()
|
||||||
w, _ := tm.Size()
|
return termWidth
|
||||||
return w
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TermHeight returns the current terminal's height.
|
// TermHeight returns the current terminal's height.
|
||||||
func TermHeight() int {
|
func TermHeight() int {
|
||||||
tm.Sync()
|
termSync()
|
||||||
_, h := tm.Size()
|
return termHeight
|
||||||
return h
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render renders all Bufferer in the given order from left to right,
|
// Render renders all Bufferer in the given order from left to right,
|
||||||
// right could overlap on left ones.
|
// right could overlap on left ones.
|
||||||
func Render(rs ...Bufferer) {
|
func render(bs ...Bufferer) {
|
||||||
tm.Clear(tm.ColorDefault, toTmAttr(theme.BodyBg))
|
|
||||||
for _, r := range rs {
|
for _, b := range bs {
|
||||||
buf := r.Buffer()
|
|
||||||
for _, v := range buf {
|
buf := b.Buffer()
|
||||||
tm.SetCell(v.X, v.Y, v.Ch, toTmAttr(v.Fg), toTmAttr(v.Bg))
|
// set cels in buf
|
||||||
|
for p, c := range buf.CellMap {
|
||||||
|
if p.In(buf.Area) {
|
||||||
|
|
||||||
|
tm.SetCell(p.X, p.Y, c.Ch, toTmAttr(c.Fg), toTmAttr(c.Bg))
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
renderLock.Lock()
|
||||||
|
// render
|
||||||
|
tm.Flush()
|
||||||
|
renderLock.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
func Clear() {
|
||||||
|
tm.Clear(tm.ColorDefault, toTmAttr(ThemeAttr("bg")))
|
||||||
|
}
|
||||||
|
|
||||||
|
func clearArea(r image.Rectangle, bg Attribute) {
|
||||||
|
for i := r.Min.X; i < r.Max.X; i++ {
|
||||||
|
for j := r.Min.Y; j < r.Max.Y; j++ {
|
||||||
|
tm.SetCell(i, j, ' ', tm.ColorDefault, toTmAttr(bg))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ClearArea(r image.Rectangle, bg Attribute) {
|
||||||
|
clearArea(r, bg)
|
||||||
tm.Flush()
|
tm.Flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var renderJobs chan []Bufferer
|
||||||
|
|
||||||
|
func Render(bs ...Bufferer) {
|
||||||
|
//go func() { renderJobs <- bs }()
|
||||||
|
renderJobs <- bs
|
||||||
|
}
|
||||||
|
|
|
||||||
85
Godeps/_workspace/src/github.com/gizak/termui/sparkline.go
generated
vendored
|
|
@ -1,12 +1,10 @@
|
||||||
// Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved.
|
// Copyright 2016 Zack Guo <gizak@icloud.com>. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license that can
|
// Use of this source code is governed by a MIT license that can
|
||||||
// be found in the LICENSE file.
|
// be found in the LICENSE file.
|
||||||
|
|
||||||
package termui
|
package termui
|
||||||
|
|
||||||
import "math"
|
// Sparkline is like: ▅▆▂▂▅▇▂▂▃▆▆▆▅▃. The data points should be non-negative integers.
|
||||||
|
|
||||||
// Sparkline is like: ▅▆▂▂▅▇▂▂▃▆▆▆▅▃
|
|
||||||
/*
|
/*
|
||||||
data := []int{4, 2, 1, 6, 3, 9, 1, 4, 2, 15, 14, 9, 8, 6, 10, 13, 15, 12, 10, 5, 3, 6, 1}
|
data := []int{4, 2, 1, 6, 3, 9, 1, 4, 2, 15, 14, 9, 8, 6, 10, 13, 15, 12, 10, 5, 3, 6, 1}
|
||||||
spl := termui.NewSparkline()
|
spl := termui.NewSparkline()
|
||||||
|
|
@ -25,7 +23,7 @@ type Sparkline struct {
|
||||||
max int
|
max int
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sparklines is a renderable widget which groups together the given sparklines.
|
// Sparklines is a renderable widget which groups togexper the given sparklines.
|
||||||
/*
|
/*
|
||||||
spls := termui.NewSparklines(spl0,spl1,spl2) //...
|
spls := termui.NewSparklines(spl0,spl1,spl2) //...
|
||||||
spls.Height = 2
|
spls.Height = 2
|
||||||
|
|
@ -49,8 +47,8 @@ func (s *Sparklines) Add(sl Sparkline) {
|
||||||
func NewSparkline() Sparkline {
|
func NewSparkline() Sparkline {
|
||||||
return Sparkline{
|
return Sparkline{
|
||||||
Height: 1,
|
Height: 1,
|
||||||
TitleColor: theme.SparklineTitle,
|
TitleColor: ThemeAttr("sparkline.title.fg"),
|
||||||
LineColor: theme.SparklineLine}
|
LineColor: ThemeAttr("sparkline.line.fg")}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSparklines return a new *Spaklines with given Sparkline(s), you can always add a new Sparkline later.
|
// NewSparklines return a new *Spaklines with given Sparkline(s), you can always add a new Sparkline later.
|
||||||
|
|
@ -67,13 +65,13 @@ func (sl *Sparklines) update() {
|
||||||
sl.Lines[i].displayHeight = v.Height + 1
|
sl.Lines[i].displayHeight = v.Height + 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sl.displayWidth = sl.innerWidth
|
sl.displayWidth = sl.innerArea.Dx()
|
||||||
|
|
||||||
// get how many lines gotta display
|
// get how many lines gotta display
|
||||||
h := 0
|
h := 0
|
||||||
sl.displayLines = 0
|
sl.displayLines = 0
|
||||||
for _, v := range sl.Lines {
|
for _, v := range sl.Lines {
|
||||||
if h+v.displayHeight <= sl.innerHeight {
|
if h+v.displayHeight <= sl.innerArea.Dy() {
|
||||||
sl.displayLines++
|
sl.displayLines++
|
||||||
} else {
|
} else {
|
||||||
break
|
break
|
||||||
|
|
@ -84,20 +82,24 @@ func (sl *Sparklines) update() {
|
||||||
for i := 0; i < sl.displayLines; i++ {
|
for i := 0; i < sl.displayLines; i++ {
|
||||||
data := sl.Lines[i].Data
|
data := sl.Lines[i].Data
|
||||||
|
|
||||||
max := math.MinInt32
|
max := 0
|
||||||
for _, v := range data {
|
for _, v := range data {
|
||||||
if max < v {
|
if max < v {
|
||||||
max = v
|
max = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sl.Lines[i].max = max
|
sl.Lines[i].max = max
|
||||||
sl.Lines[i].scale = float32(8*sl.Lines[i].Height) / float32(max)
|
if max != 0 {
|
||||||
|
sl.Lines[i].scale = float32(8*sl.Lines[i].Height) / float32(max)
|
||||||
|
} else { // when all negative
|
||||||
|
sl.Lines[i].scale = 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Buffer implements Bufferer interface.
|
// Buffer implements Bufferer interface.
|
||||||
func (sl *Sparklines) Buffer() []Point {
|
func (sl *Sparklines) Buffer() Buffer {
|
||||||
ps := sl.Block.Buffer()
|
buf := sl.Block.Buffer()
|
||||||
sl.update()
|
sl.update()
|
||||||
|
|
||||||
oftY := 0
|
oftY := 0
|
||||||
|
|
@ -105,52 +107,61 @@ func (sl *Sparklines) Buffer() []Point {
|
||||||
l := sl.Lines[i]
|
l := sl.Lines[i]
|
||||||
data := l.Data
|
data := l.Data
|
||||||
|
|
||||||
if len(data) > sl.innerWidth {
|
if len(data) > sl.innerArea.Dx() {
|
||||||
data = data[len(data)-sl.innerWidth:]
|
data = data[len(data)-sl.innerArea.Dx():]
|
||||||
}
|
}
|
||||||
|
|
||||||
if l.Title != "" {
|
if l.Title != "" {
|
||||||
rs := trimStr2Runes(l.Title, sl.innerWidth)
|
rs := trimStr2Runes(l.Title, sl.innerArea.Dx())
|
||||||
oftX := 0
|
oftX := 0
|
||||||
for _, v := range rs {
|
for _, v := range rs {
|
||||||
w := charWidth(v)
|
w := charWidth(v)
|
||||||
p := Point{}
|
c := Cell{
|
||||||
p.Ch = v
|
Ch: v,
|
||||||
p.Fg = l.TitleColor
|
Fg: l.TitleColor,
|
||||||
p.Bg = sl.BgColor
|
Bg: sl.Bg,
|
||||||
p.X = sl.innerX + oftX
|
}
|
||||||
p.Y = sl.innerY + oftY
|
x := sl.innerArea.Min.X + oftX
|
||||||
ps = append(ps, p)
|
y := sl.innerArea.Min.Y + oftY
|
||||||
|
buf.Set(x, y, c)
|
||||||
oftX += w
|
oftX += w
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for j, v := range data {
|
for j, v := range data {
|
||||||
|
// display height of the data point, zero when data is negative
|
||||||
h := int(float32(v)*l.scale + 0.5)
|
h := int(float32(v)*l.scale + 0.5)
|
||||||
|
if v < 0 {
|
||||||
|
h = 0
|
||||||
|
}
|
||||||
|
|
||||||
barCnt := h / 8
|
barCnt := h / 8
|
||||||
barMod := h % 8
|
barMod := h % 8
|
||||||
for jj := 0; jj < barCnt; jj++ {
|
for jj := 0; jj < barCnt; jj++ {
|
||||||
p := Point{}
|
c := Cell{
|
||||||
p.X = sl.innerX + j
|
Ch: ' ', // => sparks[7]
|
||||||
p.Y = sl.innerY + oftY + l.Height - jj
|
Bg: l.LineColor,
|
||||||
p.Ch = ' ' // => sparks[7]
|
}
|
||||||
p.Bg = l.LineColor
|
x := sl.innerArea.Min.X + j
|
||||||
|
y := sl.innerArea.Min.Y + oftY + l.Height - jj
|
||||||
|
|
||||||
//p.Bg = sl.BgColor
|
//p.Bg = sl.BgColor
|
||||||
ps = append(ps, p)
|
buf.Set(x, y, c)
|
||||||
}
|
}
|
||||||
if barMod != 0 {
|
if barMod != 0 {
|
||||||
p := Point{}
|
c := Cell{
|
||||||
p.X = sl.innerX + j
|
Ch: sparks[barMod-1],
|
||||||
p.Y = sl.innerY + oftY + l.Height - barCnt
|
Fg: l.LineColor,
|
||||||
p.Ch = sparks[barMod-1]
|
Bg: sl.Bg,
|
||||||
p.Fg = l.LineColor
|
}
|
||||||
p.Bg = sl.BgColor
|
x := sl.innerArea.Min.X + j
|
||||||
ps = append(ps, p)
|
y := sl.innerArea.Min.Y + oftY + l.Height - barCnt
|
||||||
|
buf.Set(x, y, c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
oftY += l.displayHeight
|
oftY += l.displayHeight
|
||||||
}
|
}
|
||||||
|
|
||||||
return sl.Block.chopOverflow(ps)
|
return buf
|
||||||
}
|
}
|
||||||
|
|
|
||||||
66
Godeps/_workspace/src/github.com/gizak/termui/test/runtest.go
generated
vendored
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
// Copyright 2016 Zack Guo <gizak@icloud.com>. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT license that can
|
||||||
|
// be found in the LICENSE file.
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/gizak/termui"
|
||||||
|
"github.com/gizak/termui/debug"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// run as client
|
||||||
|
if len(os.Args) > 1 {
|
||||||
|
fmt.Print(debug.ConnectAndListen())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// run as server
|
||||||
|
go func() { panic(debug.ListenAndServe()) }()
|
||||||
|
|
||||||
|
if err := termui.Init(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
defer termui.Close()
|
||||||
|
|
||||||
|
//termui.UseTheme("helloworld")
|
||||||
|
b := termui.NewBlock()
|
||||||
|
b.Width = 20
|
||||||
|
b.Height = 20
|
||||||
|
b.Float = termui.AlignCenter
|
||||||
|
b.BorderLabel = "[HELLO](fg-red,bg-white) [WORLD](fg-blue,bg-green)"
|
||||||
|
|
||||||
|
termui.Render(b)
|
||||||
|
|
||||||
|
termui.Handle("/sys", func(e termui.Event) {
|
||||||
|
k, ok := e.Data.(termui.EvtKbd)
|
||||||
|
debug.Logf("->%v\n", e)
|
||||||
|
if ok && k.KeyStr == "q" {
|
||||||
|
termui.StopLoop()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
termui.Handle(("/usr"), func(e termui.Event) {
|
||||||
|
debug.Logf("->%v\n", e)
|
||||||
|
})
|
||||||
|
|
||||||
|
termui.Handle("/timer/1s", func(e termui.Event) {
|
||||||
|
t := e.Data.(termui.EvtTimer)
|
||||||
|
termui.SendCustomEvt("/usr/t", t.Count)
|
||||||
|
|
||||||
|
if t.Count%2 == 0 {
|
||||||
|
b.BorderLabel = "[HELLO](fg-red,bg-green) [WORLD](fg-blue,bg-white)"
|
||||||
|
} else {
|
||||||
|
b.BorderLabel = "[HELLO](fg-blue,bg-white) [WORLD](fg-red,bg-green)"
|
||||||
|
}
|
||||||
|
|
||||||
|
termui.Render(b)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
termui.Loop()
|
||||||
|
}
|
||||||
215
Godeps/_workspace/src/github.com/gizak/termui/textbuilder.go
generated
vendored
Normal file
|
|
@ -0,0 +1,215 @@
|
||||||
|
// Copyright 2016 Zack Guo <gizak@icloud.com>. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT license that can
|
||||||
|
// be found in the LICENSE file.
|
||||||
|
|
||||||
|
package termui
|
||||||
|
|
||||||
|
import (
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TextBuilder is a minial interface to produce text []Cell using sepcific syntax (markdown).
|
||||||
|
type TextBuilder interface {
|
||||||
|
Build(s string, fg, bg Attribute) []Cell
|
||||||
|
}
|
||||||
|
|
||||||
|
// DefaultTxBuilder is set to be MarkdownTxBuilder.
|
||||||
|
var DefaultTxBuilder = NewMarkdownTxBuilder()
|
||||||
|
|
||||||
|
// MarkdownTxBuilder implements TextBuilder interface, using markdown syntax.
|
||||||
|
type MarkdownTxBuilder struct {
|
||||||
|
baseFg Attribute
|
||||||
|
baseBg Attribute
|
||||||
|
plainTx []rune
|
||||||
|
markers []marker
|
||||||
|
}
|
||||||
|
|
||||||
|
type marker struct {
|
||||||
|
st int
|
||||||
|
ed int
|
||||||
|
fg Attribute
|
||||||
|
bg Attribute
|
||||||
|
}
|
||||||
|
|
||||||
|
var colorMap = map[string]Attribute{
|
||||||
|
"red": ColorRed,
|
||||||
|
"blue": ColorBlue,
|
||||||
|
"black": ColorBlack,
|
||||||
|
"cyan": ColorCyan,
|
||||||
|
"yellow": ColorYellow,
|
||||||
|
"white": ColorWhite,
|
||||||
|
"default": ColorDefault,
|
||||||
|
"green": ColorGreen,
|
||||||
|
"magenta": ColorMagenta,
|
||||||
|
}
|
||||||
|
|
||||||
|
var attrMap = map[string]Attribute{
|
||||||
|
"bold": AttrBold,
|
||||||
|
"underline": AttrUnderline,
|
||||||
|
"reverse": AttrReverse,
|
||||||
|
}
|
||||||
|
|
||||||
|
func rmSpc(s string) string {
|
||||||
|
reg := regexp.MustCompile(`\s+`)
|
||||||
|
return reg.ReplaceAllString(s, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
// readAttr translates strings like `fg-red,fg-bold,bg-white` to fg and bg Attribute
|
||||||
|
func (mtb MarkdownTxBuilder) readAttr(s string) (Attribute, Attribute) {
|
||||||
|
fg := mtb.baseFg
|
||||||
|
bg := mtb.baseBg
|
||||||
|
|
||||||
|
updateAttr := func(a Attribute, attrs []string) Attribute {
|
||||||
|
for _, s := range attrs {
|
||||||
|
// replace the color
|
||||||
|
if c, ok := colorMap[s]; ok {
|
||||||
|
a &= 0xFF00 // erase clr 0 ~ 8 bits
|
||||||
|
a |= c // set clr
|
||||||
|
}
|
||||||
|
// add attrs
|
||||||
|
if c, ok := attrMap[s]; ok {
|
||||||
|
a |= c
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
ss := strings.Split(s, ",")
|
||||||
|
fgs := []string{}
|
||||||
|
bgs := []string{}
|
||||||
|
for _, v := range ss {
|
||||||
|
subs := strings.Split(v, "-")
|
||||||
|
if len(subs) > 1 {
|
||||||
|
if subs[0] == "fg" {
|
||||||
|
fgs = append(fgs, subs[1])
|
||||||
|
}
|
||||||
|
if subs[0] == "bg" {
|
||||||
|
bgs = append(bgs, subs[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fg = updateAttr(fg, fgs)
|
||||||
|
bg = updateAttr(bg, bgs)
|
||||||
|
return fg, bg
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mtb *MarkdownTxBuilder) reset() {
|
||||||
|
mtb.plainTx = []rune{}
|
||||||
|
mtb.markers = []marker{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse streams and parses text into normalized text and render sequence.
|
||||||
|
func (mtb *MarkdownTxBuilder) parse(str string) {
|
||||||
|
rs := str2runes(str)
|
||||||
|
normTx := []rune{}
|
||||||
|
square := []rune{}
|
||||||
|
brackt := []rune{}
|
||||||
|
accSquare := false
|
||||||
|
accBrackt := false
|
||||||
|
cntSquare := 0
|
||||||
|
|
||||||
|
reset := func() {
|
||||||
|
square = []rune{}
|
||||||
|
brackt = []rune{}
|
||||||
|
accSquare = false
|
||||||
|
accBrackt = false
|
||||||
|
cntSquare = 0
|
||||||
|
}
|
||||||
|
// pipe stacks into normTx and clear
|
||||||
|
rollback := func() {
|
||||||
|
normTx = append(normTx, square...)
|
||||||
|
normTx = append(normTx, brackt...)
|
||||||
|
reset()
|
||||||
|
}
|
||||||
|
// chop first and last
|
||||||
|
chop := func(s []rune) []rune {
|
||||||
|
return s[1 : len(s)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, r := range rs {
|
||||||
|
switch {
|
||||||
|
// stacking brackt
|
||||||
|
case accBrackt:
|
||||||
|
brackt = append(brackt, r)
|
||||||
|
if ')' == r {
|
||||||
|
fg, bg := mtb.readAttr(string(chop(brackt)))
|
||||||
|
st := len(normTx)
|
||||||
|
ed := len(normTx) + len(square) - 2
|
||||||
|
mtb.markers = append(mtb.markers, marker{st, ed, fg, bg})
|
||||||
|
normTx = append(normTx, chop(square)...)
|
||||||
|
reset()
|
||||||
|
} else if i+1 == len(rs) {
|
||||||
|
rollback()
|
||||||
|
}
|
||||||
|
// stacking square
|
||||||
|
case accSquare:
|
||||||
|
switch {
|
||||||
|
// squares closed and followed by a '('
|
||||||
|
case cntSquare == 0 && '(' == r:
|
||||||
|
accBrackt = true
|
||||||
|
brackt = append(brackt, '(')
|
||||||
|
// squares closed but not followed by a '('
|
||||||
|
case cntSquare == 0:
|
||||||
|
rollback()
|
||||||
|
if '[' == r {
|
||||||
|
accSquare = true
|
||||||
|
cntSquare = 1
|
||||||
|
brackt = append(brackt, '[')
|
||||||
|
} else {
|
||||||
|
normTx = append(normTx, r)
|
||||||
|
}
|
||||||
|
// hit the end
|
||||||
|
case i+1 == len(rs):
|
||||||
|
square = append(square, r)
|
||||||
|
rollback()
|
||||||
|
case '[' == r:
|
||||||
|
cntSquare++
|
||||||
|
square = append(square, '[')
|
||||||
|
case ']' == r:
|
||||||
|
cntSquare--
|
||||||
|
square = append(square, ']')
|
||||||
|
// normal char
|
||||||
|
default:
|
||||||
|
square = append(square, r)
|
||||||
|
}
|
||||||
|
// stacking normTx
|
||||||
|
default:
|
||||||
|
if '[' == r {
|
||||||
|
accSquare = true
|
||||||
|
cntSquare = 1
|
||||||
|
square = append(square, '[')
|
||||||
|
} else {
|
||||||
|
normTx = append(normTx, r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mtb.plainTx = normTx
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build implements TextBuilder interface.
|
||||||
|
func (mtb MarkdownTxBuilder) Build(s string, fg, bg Attribute) []Cell {
|
||||||
|
mtb.baseFg = fg
|
||||||
|
mtb.baseBg = bg
|
||||||
|
mtb.reset()
|
||||||
|
mtb.parse(s)
|
||||||
|
cs := make([]Cell, len(mtb.plainTx))
|
||||||
|
for i := range cs {
|
||||||
|
cs[i] = Cell{Ch: mtb.plainTx[i], Fg: fg, Bg: bg}
|
||||||
|
}
|
||||||
|
for _, mrk := range mtb.markers {
|
||||||
|
for i := mrk.st; i < mrk.ed; i++ {
|
||||||
|
cs[i].Fg = mrk.fg
|
||||||
|
cs[i].Bg = mrk.bg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cs
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMarkdownTxBuilder returns a TextBuilder employing markdown syntax.
|
||||||
|
func NewMarkdownTxBuilder() TextBuilder {
|
||||||
|
return MarkdownTxBuilder{}
|
||||||
|
}
|
||||||
58
Godeps/_workspace/src/github.com/gizak/termui/theme.go
generated
vendored
|
|
@ -1,9 +1,12 @@
|
||||||
// Copyright 2015 Zack Guo <gizak@icloud.com>. All rights reserved.
|
// Copyright 2016 Zack Guo <gizak@icloud.com>. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license that can
|
// Use of this source code is governed by a MIT license that can
|
||||||
// be found in the LICENSE file.
|
// be found in the LICENSE file.
|
||||||
|
|
||||||
package termui
|
package termui
|
||||||
|
|
||||||
|
import "strings"
|
||||||
|
|
||||||
|
/*
|
||||||
// A ColorScheme represents the current look-and-feel of the dashboard.
|
// A ColorScheme represents the current look-and-feel of the dashboard.
|
||||||
type ColorScheme struct {
|
type ColorScheme struct {
|
||||||
BodyBg Attribute
|
BodyBg Attribute
|
||||||
|
|
@ -29,6 +32,7 @@ type ColorScheme struct {
|
||||||
MBarChartBar Attribute
|
MBarChartBar Attribute
|
||||||
MBarChartText Attribute
|
MBarChartText Attribute
|
||||||
MBarChartNum Attribute
|
MBarChartNum Attribute
|
||||||
|
TabActiveBg Attribute
|
||||||
}
|
}
|
||||||
|
|
||||||
// default color scheme depends on the user's terminal setting.
|
// default color scheme depends on the user's terminal setting.
|
||||||
|
|
@ -58,6 +62,7 @@ var themeHelloWorld = ColorScheme{
|
||||||
MBarChartBar: ColorRed,
|
MBarChartBar: ColorRed,
|
||||||
MBarChartNum: ColorWhite,
|
MBarChartNum: ColorWhite,
|
||||||
MBarChartText: ColorCyan,
|
MBarChartText: ColorCyan,
|
||||||
|
TabActiveBg: ColorMagenta,
|
||||||
}
|
}
|
||||||
|
|
||||||
var theme = themeDefault // global dep
|
var theme = themeDefault // global dep
|
||||||
|
|
@ -82,3 +87,54 @@ func UseTheme(th string) {
|
||||||
theme = themeDefault
|
theme = themeDefault
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
var ColorMap = map[string]Attribute{
|
||||||
|
"fg": ColorWhite,
|
||||||
|
"bg": ColorDefault,
|
||||||
|
"border.fg": ColorWhite,
|
||||||
|
"label.fg": ColorGreen,
|
||||||
|
"par.fg": ColorYellow,
|
||||||
|
"par.label.bg": ColorWhite,
|
||||||
|
}
|
||||||
|
|
||||||
|
func ThemeAttr(name string) Attribute {
|
||||||
|
return lookUpAttr(ColorMap, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func lookUpAttr(clrmap map[string]Attribute, name string) Attribute {
|
||||||
|
|
||||||
|
a, ok := clrmap[name]
|
||||||
|
if ok {
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
ns := strings.Split(name, ".")
|
||||||
|
for i := range ns {
|
||||||
|
nn := strings.Join(ns[i:len(ns)], ".")
|
||||||
|
a, ok = ColorMap[nn]
|
||||||
|
if ok {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// 0<=r,g,b <= 5
|
||||||
|
func ColorRGB(r, g, b int) Attribute {
|
||||||
|
within := func(n int) int {
|
||||||
|
if n < 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if n > 5 {
|
||||||
|
return 5
|
||||||
|
}
|
||||||
|
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
r, b, g = within(r), within(b), within(g)
|
||||||
|
return Attribute(0x0f + 36*r + 6*g + b)
|
||||||
|
}
|
||||||
|
|
|
||||||
94
Godeps/_workspace/src/github.com/gizak/termui/widget.go
generated
vendored
Normal file
|
|
@ -0,0 +1,94 @@
|
||||||
|
// Copyright 2016 Zack Guo <gizak@icloud.com>. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT license that can
|
||||||
|
// be found in the LICENSE file.
|
||||||
|
|
||||||
|
package termui
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
// event mixins
|
||||||
|
type WgtMgr map[string]WgtInfo
|
||||||
|
|
||||||
|
type WgtInfo struct {
|
||||||
|
Handlers map[string]func(Event)
|
||||||
|
WgtRef Widget
|
||||||
|
Id string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Widget interface {
|
||||||
|
Id() string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewWgtInfo(wgt Widget) WgtInfo {
|
||||||
|
return WgtInfo{
|
||||||
|
Handlers: make(map[string]func(Event)),
|
||||||
|
WgtRef: wgt,
|
||||||
|
Id: wgt.Id(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewWgtMgr() WgtMgr {
|
||||||
|
wm := WgtMgr(make(map[string]WgtInfo))
|
||||||
|
return wm
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm WgtMgr) AddWgt(wgt Widget) {
|
||||||
|
wm[wgt.Id()] = NewWgtInfo(wgt)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm WgtMgr) RmWgt(wgt Widget) {
|
||||||
|
wm.RmWgtById(wgt.Id())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm WgtMgr) RmWgtById(id string) {
|
||||||
|
delete(wm, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm WgtMgr) AddWgtHandler(id, path string, h func(Event)) {
|
||||||
|
if w, ok := wm[id]; ok {
|
||||||
|
w.Handlers[path] = h
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm WgtMgr) RmWgtHandler(id, path string) {
|
||||||
|
if w, ok := wm[id]; ok {
|
||||||
|
delete(w.Handlers, path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var counter struct {
|
||||||
|
sync.RWMutex
|
||||||
|
count int
|
||||||
|
}
|
||||||
|
|
||||||
|
func GenId() string {
|
||||||
|
counter.Lock()
|
||||||
|
defer counter.Unlock()
|
||||||
|
|
||||||
|
counter.count += 1
|
||||||
|
return fmt.Sprintf("%d", counter.count)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm WgtMgr) WgtHandlersHook() func(Event) {
|
||||||
|
return func(e Event) {
|
||||||
|
for _, v := range wm {
|
||||||
|
if k := findMatch(v.Handlers, e.Path); k != "" {
|
||||||
|
v.Handlers[k](e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var DefaultWgtMgr WgtMgr
|
||||||
|
|
||||||
|
func (b *Block) Handle(path string, handler func(Event)) {
|
||||||
|
if _, ok := DefaultWgtMgr[b.Id()]; !ok {
|
||||||
|
DefaultWgtMgr.AddWgt(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
DefaultWgtMgr.AddWgtHandler(b.Id(), path, handler)
|
||||||
|
}
|
||||||
15
Godeps/_workspace/src/github.com/golang/snappy/AUTHORS
generated
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
# This is the official list of Snappy-Go authors for copyright purposes.
|
||||||
|
# This file is distinct from the CONTRIBUTORS files.
|
||||||
|
# See the latter for an explanation.
|
||||||
|
|
||||||
|
# Names should be added to this file as
|
||||||
|
# Name or Organization <email address>
|
||||||
|
# The email address is not required for organizations.
|
||||||
|
|
||||||
|
# Please keep the list sorted.
|
||||||
|
|
||||||
|
Damian Gryski <dgryski@gmail.com>
|
||||||
|
Google Inc.
|
||||||
|
Jan Mercl <0xjnml@gmail.com>
|
||||||
|
Rodolfo Carvalho <rhcarvalho@gmail.com>
|
||||||
|
Sebastien Binet <seb.binet@gmail.com>
|
||||||