diff --git a/CHANGELOG.md b/CHANGELOG.md index 410102a9cf..06a5107c6f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,7 +22,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - added `-d,--dmsghttp` flag to `skywire-cli config gen` - added `dmsgdirect` client to connect to services over dmsg - added `-f` flag to skywire-visor to configure a visor to expose hypervisor UI with default values at runtime -- added `host-keeper` update routine on starting visor process. ## 0.5.0 ### Changed diff --git a/cmd/skywire-visor/commands/root.go b/cmd/skywire-visor/commands/root.go index 99d6f89666..dee7ab2040 100644 --- a/cmd/skywire-visor/commands/root.go +++ b/cmd/skywire-visor/commands/root.go @@ -114,8 +114,6 @@ func runVisor(args []string) { } vis.SetLogstore(store) - go vis.HostKeeper(os.Getenv("SKYBIAN_BUILD_VERSION")) - if launchBrowser { runBrowser(conf, log) } diff --git a/go.mod b/go.mod index a257d1ba2c..9357831674 100644 --- a/go.mod +++ b/go.mod @@ -51,10 +51,7 @@ require ( nhooyr.io/websocket v1.8.2 ) -require ( - github.com/james-barrow/golang-ipc v0.0.0-20210227130457-95e7cc81f5e2 - github.com/jaypipes/ghw v0.8.0 -) +require github.com/james-barrow/golang-ipc v0.0.0-20210227130457-95e7cc81f5e2 require ( github.com/ActiveState/termtest/conpty v0.5.0 // indirect @@ -68,7 +65,6 @@ require ( github.com/getlantern/context v0.0.0-20190109183933-c447772a6520 // indirect github.com/getlantern/errors v1.0.1 // indirect github.com/getlantern/hex v0.0.0-20190417191902-c6586a6fe0b7 // indirect - github.com/ghodss/yaml v1.0.0 // indirect github.com/go-ole/go-ole v1.2.4 // indirect github.com/go-stack/stack v1.8.0 // indirect github.com/golang/gddo v0.0.0-20190419222130-af0f2af80721 // indirect @@ -76,13 +72,11 @@ require ( github.com/google/go-querystring v1.0.0 // indirect github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect - github.com/jaypipes/pcidb v0.6.0 // indirect github.com/klauspost/compress v1.11.0 // indirect github.com/klauspost/cpuid v1.2.4 // indirect github.com/klauspost/pgzip v1.2.1 // indirect github.com/mattn/go-isatty v0.0.14 // indirect github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect - github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/nwaples/rardecode v1.0.0 // indirect @@ -102,9 +96,7 @@ require ( golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect golang.org/x/mod v0.4.2 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect - howett.net/plist v0.0.0-20181124034731-591f970eefbb // indirect ) // Uncomment for tests with alternate branches of 'dmsg' diff --git a/go.sum b/go.sum index b8d1625b5b..248035c4dc 100644 --- a/go.sum +++ b/go.sum @@ -136,7 +136,6 @@ github.com/getlantern/ops v0.0.0-20200403153110-8476b16edcd6 h1:QthAQCekS1YOeYWS github.com/getlantern/ops v0.0.0-20200403153110-8476b16edcd6/go.mod h1:D5ao98qkA6pxftxoqzibIBBrLSUli+kYnJqrgBf9cIA= github.com/getlantern/systray v1.1.0 h1:U0wCEqseLi2ok1fE6b88gJklzriavPJixZysZPkZd/Y= github.com/getlantern/systray v1.1.0/go.mod h1:AecygODWIsBquJCJFop8MEQcJbWFfw/1yWbVabNgpCM= -github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-chi/chi v4.1.2+incompatible h1:fGFk2Gmi/YKXk0OmGfBh0WgmN3XB8lVnEyNz34tQRec= @@ -271,12 +270,7 @@ github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NH github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/james-barrow/golang-ipc v0.0.0-20210227130457-95e7cc81f5e2 h1:lnIIG509NeyPk/15ZHqP3DwTTQXqp2PoQoxGdYDC2h4= github.com/james-barrow/golang-ipc v0.0.0-20210227130457-95e7cc81f5e2/go.mod h1:M3eGiVVY7bdtqyWT+gtbIqji7CqHi3PKJHSPl2pP40c= -github.com/jaypipes/ghw v0.8.0 h1:02q1pTm9CD83vuhBsEZZhOCS128pq87uyaQeJZkp3sQ= -github.com/jaypipes/ghw v0.8.0/go.mod h1:+gR9bjm3W/HnFi90liF+Fj9GpCe/Dsibl9Im8KmC7c4= -github.com/jaypipes/pcidb v0.6.0 h1:VIM7GKVaW4qba30cvB67xSCgJPTzkG8Kzw/cbs5PHWU= -github.com/jaypipes/pcidb v0.6.0/go.mod h1:L2RGk04sfRhp5wvHO0gfRAMoLY/F3PKv/nwJeVoho0o= github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -342,7 +336,6 @@ github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceT github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ= github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= @@ -383,7 +376,6 @@ github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCko github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pires/go-proxyproto v0.3.3/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -454,13 +446,11 @@ github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v1.2.1 h1:+KmjbUw1hriSNMF55oPrkZcb27aECyrj8V2ytv7kWDw= github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= -github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= @@ -933,7 +923,6 @@ gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= @@ -947,8 +936,6 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -howett.net/plist v0.0.0-20181124034731-591f970eefbb h1:jhnBjNi9UFpfpl8YZhA9CrOqpnJdvzuiHsl/dnxl11M= -howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0= nhooyr.io/websocket v1.8.2 h1:LwdzfyyOZKtVFoXay6A39Acu03KmidSZ3YUUvPa13PA= nhooyr.io/websocket v1.8.2/go.mod h1:LiqdCg1Cu7TPWxEvPjPa0TGYxCsy4pHNTN9gGluwBpQ= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/pkg/skyenv/values.go b/pkg/skyenv/values.go index 9a46382270..ee01ce3412 100644 --- a/pkg/skyenv/values.go +++ b/pkg/skyenv/values.go @@ -31,7 +31,6 @@ const ( DefaultRouteFinderAddr = "http://rf.skywire.skycoin.com" DefaultUptimeTrackerAddr = "http://ut.skywire.skycoin.com" DefaultAddressResolverAddr = "http://ar.skywire.skycoin.com" - DefaultHostKeeperAddr = "http://hk.skywire.skycoin.com" DefaultSetupPK = "0324579f003e6b4048bae2def4365e634d8e0e3054a20fc7af49daf2a179658557" ) @@ -43,7 +42,6 @@ const ( TestRouteFinderAddr = "http://rf.skywire.dev" TestUptimeTrackerAddr = "http://ut.skywire.dev" TestAddressResolverAddr = "http://ar.skywire.dev" - TestHostKeeperAddr = "http://hk.skywire.dev" TestSetupPK = "026c2a3e92d6253c5abd71a42628db6fca9dd9aa037ab6f4e3a31108558dfd87cf" ) diff --git a/pkg/visor/visor.go b/pkg/visor/visor.go index 42447b6486..6f4b580040 100644 --- a/pkg/visor/visor.go +++ b/pkg/visor/visor.go @@ -2,25 +2,18 @@ package visor import ( - "bytes" "context" - "encoding/json" "errors" "fmt" "net/http" - "os/exec" "sync" "time" - "github.com/jaypipes/ghw" - "github.com/jaypipes/ghw/pkg/baseboard" - "github.com/jaypipes/ghw/pkg/product" "github.com/skycoin/dmsg" "github.com/skycoin/dmsg/cipher" dmsgdisc "github.com/skycoin/dmsg/disc" "github.com/skycoin/skycoin/src/util/logging" - "github.com/skycoin/skywire/internal/httpauth" "github.com/skycoin/skywire/internal/utclient" "github.com/skycoin/skywire/pkg/app/appdisc" "github.com/skycoin/skywire/pkg/app/appevent" @@ -240,80 +233,3 @@ func (v *Visor) SetLogstore(store logstore.Store) { func (v *Visor) tpDiscClient() transport.DiscoveryClient { return v.tpM.Conf.DiscoveryClient } - -// HostKeeper save host info of running visor. -func (v *Visor) HostKeeper(skybianBuildVersion string) { - var model, serialNumber string - logger := v.MasterLogger().PackageLogger("host-keeper") - - if skybianBuildVersion != "" { - modelByte, err := exec.Command("cat", "/proc/device-tree/model").Output() - if err != nil { - logger.Errorf("Error during get model of board due to %v", err) - return - } - model = string(modelByte) - - serialNumberByte, err := exec.Command("cat", "/proc/device-tree/serial-number").Output() - if err != nil { - logger.Errorf("Error during get serial number of board due to %v", err) - return - } - serialNumber = string(serialNumberByte) - } else { - baseboardInfo, err := baseboard.New(ghw.WithDisableWarnings()) - if err != nil { - logger.Errorf("Error during get information of host due to %v", err) - return - } - model = baseboardInfo.Vendor - serialNumber = baseboardInfo.SerialNumber - if model == "unknown" || serialNumber == "unknown" { - productInfo, err := product.New(ghw.WithDisableWarnings()) - if err != nil { - logger.Errorf("Error during get information of host due to %v", err) - return - } - model = productInfo.Vendor - serialNumber = productInfo.UUID - } - } - - var keeperInfo HostKeeperData - keeperInfo.Model = model - keeperInfo.SerialNumber = serialNumber - - logger.WithField("Info", keeperInfo).Info("Host information achieved.") - - client, err := httpauth.NewClient(context.Background(), v.conf.HostKeeper, v.conf.PK, v.conf.SK, &http.Client{}, "", v.MasterLogger()) - if err != nil { - logger.Errorf("Host Keeper httpauth: %v", err) - return - } - - keeperInfoByte, err := json.Marshal(keeperInfo) - if err != nil { - logger.Errorf("Error during marshal host info due to %v", err) - return - } - - req, err := http.NewRequest(http.MethodPost, v.conf.HostKeeper+"/update", bytes.NewReader(keeperInfoByte)) - if err != nil { - logger.Errorf("Error during make request of host info due to %v", err) - return - } - - _, err = client.Do(req) - if err != nil { - logger.Errorf("Error during send host info to host-keeper service due to %v", err) - return - } - - logger.Info("Host info successfully updated.") -} - -// HostKeeperData the struct of host keeper data -type HostKeeperData struct { - Model string - SerialNumber string -} diff --git a/pkg/visor/visorconfig/config.go b/pkg/visor/visorconfig/config.go index cc466d4516..9216878c32 100644 --- a/pkg/visor/visorconfig/config.go +++ b/pkg/visor/visorconfig/config.go @@ -52,7 +52,6 @@ func MakeBaseConfig(common *Common) *V1 { conf.StunServers = skyenv.GetStunServers() conf.ShutdownTimeout = DefaultTimeout conf.RestartCheckDelay = Duration(restart.DefaultCheckDelay) - conf.HostKeeper = skyenv.DefaultHostKeeperAddr return conf } @@ -181,7 +180,6 @@ func SetDefaultTestingValues(conf *V1) { conf.Routing.SetupNodes = []cipher.PubKey{skyenv.MustPK(skyenv.TestSetupPK)} conf.UptimeTracker.Addr = skyenv.TestUptimeTrackerAddr conf.Launcher.ServiceDisc = skyenv.TestServiceDiscAddr - conf.HostKeeper = skyenv.TestHostKeeperAddr } // SetDefaultProductionValues mutates configuration to use production values @@ -195,7 +193,6 @@ func SetDefaultProductionValues(conf *V1) { Addr: skyenv.DefaultUptimeTrackerAddr, } conf.Launcher.ServiceDisc = skyenv.DefaultServiceDiscAddr - conf.HostKeeper = skyenv.DefaultHostKeeperAddr } // makeDefaultLauncherAppsConfig creates default launcher config for apps, diff --git a/pkg/visor/visorconfig/parse.go b/pkg/visor/visorconfig/parse.go index 31e0e581a8..f96144cf8a 100644 --- a/pkg/visor/visorconfig/parse.go +++ b/pkg/visor/visorconfig/parse.go @@ -186,6 +186,5 @@ func updateUrls(conf *V1) *V1 { if conf.Launcher.ServiceDisc == skyenv.OldDefaultServiceDiscAddr { conf.Launcher.ServiceDisc = skyenv.DefaultServiceDiscAddr } - conf.HostKeeper = skyenv.DefaultHostKeeperAddr return conf } diff --git a/pkg/visor/visorconfig/v1.go b/pkg/visor/visorconfig/v1.go index 7f135a3931..493175ddf3 100644 --- a/pkg/visor/visorconfig/v1.go +++ b/pkg/visor/visorconfig/v1.go @@ -63,7 +63,6 @@ type V1 struct { ShutdownTimeout Duration `json:"shutdown_timeout,omitempty"` // time value, examples: 10s, 1m, etc RestartCheckDelay Duration `json:"restart_check_delay,omitempty"` // time value, examples: 10s, 1m, etc IsPublic bool `json:"is_public"` - HostKeeper string `json:"host_keeper"` PersistentTransports []transport.PersistentTransports `json:"persistent_transports"` diff --git a/vendor/github.com/ghodss/yaml/.gitignore b/vendor/github.com/ghodss/yaml/.gitignore deleted file mode 100644 index e256a31e00..0000000000 --- a/vendor/github.com/ghodss/yaml/.gitignore +++ /dev/null @@ -1,20 +0,0 @@ -# OSX leaves these everywhere on SMB shares -._* - -# Eclipse files -.classpath -.project -.settings/** - -# Emacs save files -*~ - -# Vim-related files -[._]*.s[a-w][a-z] -[._]s[a-w][a-z] -*.un~ -Session.vim -.netrwhist - -# Go test binaries -*.test diff --git a/vendor/github.com/ghodss/yaml/.travis.yml b/vendor/github.com/ghodss/yaml/.travis.yml deleted file mode 100644 index 0e9d6edc01..0000000000 --- a/vendor/github.com/ghodss/yaml/.travis.yml +++ /dev/null @@ -1,7 +0,0 @@ -language: go -go: - - 1.3 - - 1.4 -script: - - go test - - go build diff --git a/vendor/github.com/ghodss/yaml/LICENSE b/vendor/github.com/ghodss/yaml/LICENSE deleted file mode 100644 index 7805d36de7..0000000000 --- a/vendor/github.com/ghodss/yaml/LICENSE +++ /dev/null @@ -1,50 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014 Sam Ghods - -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. - - -Copyright (c) 2012 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/ghodss/yaml/README.md b/vendor/github.com/ghodss/yaml/README.md deleted file mode 100644 index 0200f75b4d..0000000000 --- a/vendor/github.com/ghodss/yaml/README.md +++ /dev/null @@ -1,121 +0,0 @@ -# YAML marshaling and unmarshaling support for Go - -[![Build Status](https://travis-ci.org/ghodss/yaml.svg)](https://travis-ci.org/ghodss/yaml) - -## Introduction - -A wrapper around [go-yaml](https://github.com/go-yaml/yaml) designed to enable a better way of handling YAML when marshaling to and from structs. - -In short, this library first converts YAML to JSON using go-yaml and then uses `json.Marshal` and `json.Unmarshal` to convert to or from the struct. This means that it effectively reuses the JSON struct tags as well as the custom JSON methods `MarshalJSON` and `UnmarshalJSON` unlike go-yaml. For a detailed overview of the rationale behind this method, [see this blog post](http://ghodss.com/2014/the-right-way-to-handle-yaml-in-golang/). - -## Compatibility - -This package uses [go-yaml](https://github.com/go-yaml/yaml) and therefore supports [everything go-yaml supports](https://github.com/go-yaml/yaml#compatibility). - -## Caveats - -**Caveat #1:** When using `yaml.Marshal` and `yaml.Unmarshal`, binary data should NOT be preceded with the `!!binary` YAML tag. If you do, go-yaml will convert the binary data from base64 to native binary data, which is not compatible with JSON. You can still use binary in your YAML files though - just store them without the `!!binary` tag and decode the base64 in your code (e.g. in the custom JSON methods `MarshalJSON` and `UnmarshalJSON`). This also has the benefit that your YAML and your JSON binary data will be decoded exactly the same way. As an example: - -``` -BAD: - exampleKey: !!binary gIGC - -GOOD: - exampleKey: gIGC -... and decode the base64 data in your code. -``` - -**Caveat #2:** When using `YAMLToJSON` directly, maps with keys that are maps will result in an error since this is not supported by JSON. This error will occur in `Unmarshal` as well since you can't unmarshal map keys anyways since struct fields can't be keys. - -## Installation and usage - -To install, run: - -``` -$ go get github.com/ghodss/yaml -``` - -And import using: - -``` -import "github.com/ghodss/yaml" -``` - -Usage is very similar to the JSON library: - -```go -package main - -import ( - "fmt" - - "github.com/ghodss/yaml" -) - -type Person struct { - Name string `json:"name"` // Affects YAML field names too. - Age int `json:"age"` -} - -func main() { - // Marshal a Person struct to YAML. - p := Person{"John", 30} - y, err := yaml.Marshal(p) - if err != nil { - fmt.Printf("err: %v\n", err) - return - } - fmt.Println(string(y)) - /* Output: - age: 30 - name: John - */ - - // Unmarshal the YAML back into a Person struct. - var p2 Person - err = yaml.Unmarshal(y, &p2) - if err != nil { - fmt.Printf("err: %v\n", err) - return - } - fmt.Println(p2) - /* Output: - {John 30} - */ -} -``` - -`yaml.YAMLToJSON` and `yaml.JSONToYAML` methods are also available: - -```go -package main - -import ( - "fmt" - - "github.com/ghodss/yaml" -) - -func main() { - j := []byte(`{"name": "John", "age": 30}`) - y, err := yaml.JSONToYAML(j) - if err != nil { - fmt.Printf("err: %v\n", err) - return - } - fmt.Println(string(y)) - /* Output: - name: John - age: 30 - */ - j2, err := yaml.YAMLToJSON(y) - if err != nil { - fmt.Printf("err: %v\n", err) - return - } - fmt.Println(string(j2)) - /* Output: - {"age":30,"name":"John"} - */ -} -``` diff --git a/vendor/github.com/ghodss/yaml/fields.go b/vendor/github.com/ghodss/yaml/fields.go deleted file mode 100644 index 5860074026..0000000000 --- a/vendor/github.com/ghodss/yaml/fields.go +++ /dev/null @@ -1,501 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. -package yaml - -import ( - "bytes" - "encoding" - "encoding/json" - "reflect" - "sort" - "strings" - "sync" - "unicode" - "unicode/utf8" -) - -// indirect walks down v allocating pointers as needed, -// until it gets to a non-pointer. -// if it encounters an Unmarshaler, indirect stops and returns that. -// if decodingNull is true, indirect stops at the last pointer so it can be set to nil. -func indirect(v reflect.Value, decodingNull bool) (json.Unmarshaler, encoding.TextUnmarshaler, reflect.Value) { - // If v is a named type and is addressable, - // start with its address, so that if the type has pointer methods, - // we find them. - if v.Kind() != reflect.Ptr && v.Type().Name() != "" && v.CanAddr() { - v = v.Addr() - } - for { - // Load value from interface, but only if the result will be - // usefully addressable. - if v.Kind() == reflect.Interface && !v.IsNil() { - e := v.Elem() - if e.Kind() == reflect.Ptr && !e.IsNil() && (!decodingNull || e.Elem().Kind() == reflect.Ptr) { - v = e - continue - } - } - - if v.Kind() != reflect.Ptr { - break - } - - if v.Elem().Kind() != reflect.Ptr && decodingNull && v.CanSet() { - break - } - if v.IsNil() { - if v.CanSet() { - v.Set(reflect.New(v.Type().Elem())) - } else { - v = reflect.New(v.Type().Elem()) - } - } - if v.Type().NumMethod() > 0 { - if u, ok := v.Interface().(json.Unmarshaler); ok { - return u, nil, reflect.Value{} - } - if u, ok := v.Interface().(encoding.TextUnmarshaler); ok { - return nil, u, reflect.Value{} - } - } - v = v.Elem() - } - return nil, nil, v -} - -// A field represents a single field found in a struct. -type field struct { - name string - nameBytes []byte // []byte(name) - equalFold func(s, t []byte) bool // bytes.EqualFold or equivalent - - tag bool - index []int - typ reflect.Type - omitEmpty bool - quoted bool -} - -func fillField(f field) field { - f.nameBytes = []byte(f.name) - f.equalFold = foldFunc(f.nameBytes) - return f -} - -// byName sorts field by name, breaking ties with depth, -// then breaking ties with "name came from json tag", then -// breaking ties with index sequence. -type byName []field - -func (x byName) Len() int { return len(x) } - -func (x byName) Swap(i, j int) { x[i], x[j] = x[j], x[i] } - -func (x byName) Less(i, j int) bool { - if x[i].name != x[j].name { - return x[i].name < x[j].name - } - if len(x[i].index) != len(x[j].index) { - return len(x[i].index) < len(x[j].index) - } - if x[i].tag != x[j].tag { - return x[i].tag - } - return byIndex(x).Less(i, j) -} - -// byIndex sorts field by index sequence. -type byIndex []field - -func (x byIndex) Len() int { return len(x) } - -func (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] } - -func (x byIndex) Less(i, j int) bool { - for k, xik := range x[i].index { - if k >= len(x[j].index) { - return false - } - if xik != x[j].index[k] { - return xik < x[j].index[k] - } - } - return len(x[i].index) < len(x[j].index) -} - -// typeFields returns a list of fields that JSON should recognize for the given type. -// The algorithm is breadth-first search over the set of structs to include - the top struct -// and then any reachable anonymous structs. -func typeFields(t reflect.Type) []field { - // Anonymous fields to explore at the current level and the next. - current := []field{} - next := []field{{typ: t}} - - // Count of queued names for current level and the next. - count := map[reflect.Type]int{} - nextCount := map[reflect.Type]int{} - - // Types already visited at an earlier level. - visited := map[reflect.Type]bool{} - - // Fields found. - var fields []field - - for len(next) > 0 { - current, next = next, current[:0] - count, nextCount = nextCount, map[reflect.Type]int{} - - for _, f := range current { - if visited[f.typ] { - continue - } - visited[f.typ] = true - - // Scan f.typ for fields to include. - for i := 0; i < f.typ.NumField(); i++ { - sf := f.typ.Field(i) - if sf.PkgPath != "" { // unexported - continue - } - tag := sf.Tag.Get("json") - if tag == "-" { - continue - } - name, opts := parseTag(tag) - if !isValidTag(name) { - name = "" - } - index := make([]int, len(f.index)+1) - copy(index, f.index) - index[len(f.index)] = i - - ft := sf.Type - if ft.Name() == "" && ft.Kind() == reflect.Ptr { - // Follow pointer. - ft = ft.Elem() - } - - // Record found field and index sequence. - if name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct { - tagged := name != "" - if name == "" { - name = sf.Name - } - fields = append(fields, fillField(field{ - name: name, - tag: tagged, - index: index, - typ: ft, - omitEmpty: opts.Contains("omitempty"), - quoted: opts.Contains("string"), - })) - if count[f.typ] > 1 { - // If there were multiple instances, add a second, - // so that the annihilation code will see a duplicate. - // It only cares about the distinction between 1 or 2, - // so don't bother generating any more copies. - fields = append(fields, fields[len(fields)-1]) - } - continue - } - - // Record new anonymous struct to explore in next round. - nextCount[ft]++ - if nextCount[ft] == 1 { - next = append(next, fillField(field{name: ft.Name(), index: index, typ: ft})) - } - } - } - } - - sort.Sort(byName(fields)) - - // Delete all fields that are hidden by the Go rules for embedded fields, - // except that fields with JSON tags are promoted. - - // The fields are sorted in primary order of name, secondary order - // of field index length. Loop over names; for each name, delete - // hidden fields by choosing the one dominant field that survives. - out := fields[:0] - for advance, i := 0, 0; i < len(fields); i += advance { - // One iteration per name. - // Find the sequence of fields with the name of this first field. - fi := fields[i] - name := fi.name - for advance = 1; i+advance < len(fields); advance++ { - fj := fields[i+advance] - if fj.name != name { - break - } - } - if advance == 1 { // Only one field with this name - out = append(out, fi) - continue - } - dominant, ok := dominantField(fields[i : i+advance]) - if ok { - out = append(out, dominant) - } - } - - fields = out - sort.Sort(byIndex(fields)) - - return fields -} - -// dominantField looks through the fields, all of which are known to -// have the same name, to find the single field that dominates the -// others using Go's embedding rules, modified by the presence of -// JSON tags. If there are multiple top-level fields, the boolean -// will be false: This condition is an error in Go and we skip all -// the fields. -func dominantField(fields []field) (field, bool) { - // The fields are sorted in increasing index-length order. The winner - // must therefore be one with the shortest index length. Drop all - // longer entries, which is easy: just truncate the slice. - length := len(fields[0].index) - tagged := -1 // Index of first tagged field. - for i, f := range fields { - if len(f.index) > length { - fields = fields[:i] - break - } - if f.tag { - if tagged >= 0 { - // Multiple tagged fields at the same level: conflict. - // Return no field. - return field{}, false - } - tagged = i - } - } - if tagged >= 0 { - return fields[tagged], true - } - // All remaining fields have the same length. If there's more than one, - // we have a conflict (two fields named "X" at the same level) and we - // return no field. - if len(fields) > 1 { - return field{}, false - } - return fields[0], true -} - -var fieldCache struct { - sync.RWMutex - m map[reflect.Type][]field -} - -// cachedTypeFields is like typeFields but uses a cache to avoid repeated work. -func cachedTypeFields(t reflect.Type) []field { - fieldCache.RLock() - f := fieldCache.m[t] - fieldCache.RUnlock() - if f != nil { - return f - } - - // Compute fields without lock. - // Might duplicate effort but won't hold other computations back. - f = typeFields(t) - if f == nil { - f = []field{} - } - - fieldCache.Lock() - if fieldCache.m == nil { - fieldCache.m = map[reflect.Type][]field{} - } - fieldCache.m[t] = f - fieldCache.Unlock() - return f -} - -func isValidTag(s string) bool { - if s == "" { - return false - } - for _, c := range s { - switch { - case strings.ContainsRune("!#$%&()*+-./:<=>?@[]^_{|}~ ", c): - // Backslash and quote chars are reserved, but - // otherwise any punctuation chars are allowed - // in a tag name. - default: - if !unicode.IsLetter(c) && !unicode.IsDigit(c) { - return false - } - } - } - return true -} - -const ( - caseMask = ^byte(0x20) // Mask to ignore case in ASCII. - kelvin = '\u212a' - smallLongEss = '\u017f' -) - -// foldFunc returns one of four different case folding equivalence -// functions, from most general (and slow) to fastest: -// -// 1) bytes.EqualFold, if the key s contains any non-ASCII UTF-8 -// 2) equalFoldRight, if s contains special folding ASCII ('k', 'K', 's', 'S') -// 3) asciiEqualFold, no special, but includes non-letters (including _) -// 4) simpleLetterEqualFold, no specials, no non-letters. -// -// The letters S and K are special because they map to 3 runes, not just 2: -// * S maps to s and to U+017F 'ſ' Latin small letter long s -// * k maps to K and to U+212A 'K' Kelvin sign -// See http://play.golang.org/p/tTxjOc0OGo -// -// The returned function is specialized for matching against s and -// should only be given s. It's not curried for performance reasons. -func foldFunc(s []byte) func(s, t []byte) bool { - nonLetter := false - special := false // special letter - for _, b := range s { - if b >= utf8.RuneSelf { - return bytes.EqualFold - } - upper := b & caseMask - if upper < 'A' || upper > 'Z' { - nonLetter = true - } else if upper == 'K' || upper == 'S' { - // See above for why these letters are special. - special = true - } - } - if special { - return equalFoldRight - } - if nonLetter { - return asciiEqualFold - } - return simpleLetterEqualFold -} - -// equalFoldRight is a specialization of bytes.EqualFold when s is -// known to be all ASCII (including punctuation), but contains an 's', -// 'S', 'k', or 'K', requiring a Unicode fold on the bytes in t. -// See comments on foldFunc. -func equalFoldRight(s, t []byte) bool { - for _, sb := range s { - if len(t) == 0 { - return false - } - tb := t[0] - if tb < utf8.RuneSelf { - if sb != tb { - sbUpper := sb & caseMask - if 'A' <= sbUpper && sbUpper <= 'Z' { - if sbUpper != tb&caseMask { - return false - } - } else { - return false - } - } - t = t[1:] - continue - } - // sb is ASCII and t is not. t must be either kelvin - // sign or long s; sb must be s, S, k, or K. - tr, size := utf8.DecodeRune(t) - switch sb { - case 's', 'S': - if tr != smallLongEss { - return false - } - case 'k', 'K': - if tr != kelvin { - return false - } - default: - return false - } - t = t[size:] - - } - if len(t) > 0 { - return false - } - return true -} - -// asciiEqualFold is a specialization of bytes.EqualFold for use when -// s is all ASCII (but may contain non-letters) and contains no -// special-folding letters. -// See comments on foldFunc. -func asciiEqualFold(s, t []byte) bool { - if len(s) != len(t) { - return false - } - for i, sb := range s { - tb := t[i] - if sb == tb { - continue - } - if ('a' <= sb && sb <= 'z') || ('A' <= sb && sb <= 'Z') { - if sb&caseMask != tb&caseMask { - return false - } - } else { - return false - } - } - return true -} - -// simpleLetterEqualFold is a specialization of bytes.EqualFold for -// use when s is all ASCII letters (no underscores, etc) and also -// doesn't contain 'k', 'K', 's', or 'S'. -// See comments on foldFunc. -func simpleLetterEqualFold(s, t []byte) bool { - if len(s) != len(t) { - return false - } - for i, b := range s { - if b&caseMask != t[i]&caseMask { - return false - } - } - return true -} - -// tagOptions is the string following a comma in a struct field's "json" -// tag, or the empty string. It does not include the leading comma. -type tagOptions string - -// parseTag splits a struct field's json tag into its name and -// comma-separated options. -func parseTag(tag string) (string, tagOptions) { - if idx := strings.Index(tag, ","); idx != -1 { - return tag[:idx], tagOptions(tag[idx+1:]) - } - return tag, tagOptions("") -} - -// Contains reports whether a comma-separated list of options -// contains a particular substr flag. substr must be surrounded by a -// string boundary or commas. -func (o tagOptions) Contains(optionName string) bool { - if len(o) == 0 { - return false - } - s := string(o) - for s != "" { - var next string - i := strings.Index(s, ",") - if i >= 0 { - s, next = s[:i], s[i+1:] - } - if s == optionName { - return true - } - s = next - } - return false -} diff --git a/vendor/github.com/ghodss/yaml/yaml.go b/vendor/github.com/ghodss/yaml/yaml.go deleted file mode 100644 index 4fb4054a8b..0000000000 --- a/vendor/github.com/ghodss/yaml/yaml.go +++ /dev/null @@ -1,277 +0,0 @@ -package yaml - -import ( - "bytes" - "encoding/json" - "fmt" - "reflect" - "strconv" - - "gopkg.in/yaml.v2" -) - -// Marshals the object into JSON then converts JSON to YAML and returns the -// YAML. -func Marshal(o interface{}) ([]byte, error) { - j, err := json.Marshal(o) - if err != nil { - return nil, fmt.Errorf("error marshaling into JSON: %v", err) - } - - y, err := JSONToYAML(j) - if err != nil { - return nil, fmt.Errorf("error converting JSON to YAML: %v", err) - } - - return y, nil -} - -// Converts YAML to JSON then uses JSON to unmarshal into an object. -func Unmarshal(y []byte, o interface{}) error { - vo := reflect.ValueOf(o) - j, err := yamlToJSON(y, &vo) - if err != nil { - return fmt.Errorf("error converting YAML to JSON: %v", err) - } - - err = json.Unmarshal(j, o) - if err != nil { - return fmt.Errorf("error unmarshaling JSON: %v", err) - } - - return nil -} - -// Convert JSON to YAML. -func JSONToYAML(j []byte) ([]byte, error) { - // Convert the JSON to an object. - var jsonObj interface{} - // We are using yaml.Unmarshal here (instead of json.Unmarshal) because the - // Go JSON library doesn't try to pick the right number type (int, float, - // etc.) when unmarshalling to interface{}, it just picks float64 - // universally. go-yaml does go through the effort of picking the right - // number type, so we can preserve number type throughout this process. - err := yaml.Unmarshal(j, &jsonObj) - if err != nil { - return nil, err - } - - // Marshal this object into YAML. - return yaml.Marshal(jsonObj) -} - -// Convert YAML to JSON. Since JSON is a subset of YAML, passing JSON through -// this method should be a no-op. -// -// Things YAML can do that are not supported by JSON: -// * In YAML you can have binary and null keys in your maps. These are invalid -// in JSON. (int and float keys are converted to strings.) -// * Binary data in YAML with the !!binary tag is not supported. If you want to -// use binary data with this library, encode the data as base64 as usual but do -// not use the !!binary tag in your YAML. This will ensure the original base64 -// encoded data makes it all the way through to the JSON. -func YAMLToJSON(y []byte) ([]byte, error) { - return yamlToJSON(y, nil) -} - -func yamlToJSON(y []byte, jsonTarget *reflect.Value) ([]byte, error) { - // Convert the YAML to an object. - var yamlObj interface{} - err := yaml.Unmarshal(y, &yamlObj) - if err != nil { - return nil, err - } - - // YAML objects are not completely compatible with JSON objects (e.g. you - // can have non-string keys in YAML). So, convert the YAML-compatible object - // to a JSON-compatible object, failing with an error if irrecoverable - // incompatibilties happen along the way. - jsonObj, err := convertToJSONableObject(yamlObj, jsonTarget) - if err != nil { - return nil, err - } - - // Convert this object to JSON and return the data. - return json.Marshal(jsonObj) -} - -func convertToJSONableObject(yamlObj interface{}, jsonTarget *reflect.Value) (interface{}, error) { - var err error - - // Resolve jsonTarget to a concrete value (i.e. not a pointer or an - // interface). We pass decodingNull as false because we're not actually - // decoding into the value, we're just checking if the ultimate target is a - // string. - if jsonTarget != nil { - ju, tu, pv := indirect(*jsonTarget, false) - // We have a JSON or Text Umarshaler at this level, so we can't be trying - // to decode into a string. - if ju != nil || tu != nil { - jsonTarget = nil - } else { - jsonTarget = &pv - } - } - - // If yamlObj is a number or a boolean, check if jsonTarget is a string - - // if so, coerce. Else return normal. - // If yamlObj is a map or array, find the field that each key is - // unmarshaling to, and when you recurse pass the reflect.Value for that - // field back into this function. - switch typedYAMLObj := yamlObj.(type) { - case map[interface{}]interface{}: - // JSON does not support arbitrary keys in a map, so we must convert - // these keys to strings. - // - // From my reading of go-yaml v2 (specifically the resolve function), - // keys can only have the types string, int, int64, float64, binary - // (unsupported), or null (unsupported). - strMap := make(map[string]interface{}) - for k, v := range typedYAMLObj { - // Resolve the key to a string first. - var keyString string - switch typedKey := k.(type) { - case string: - keyString = typedKey - case int: - keyString = strconv.Itoa(typedKey) - case int64: - // go-yaml will only return an int64 as a key if the system - // architecture is 32-bit and the key's value is between 32-bit - // and 64-bit. Otherwise the key type will simply be int. - keyString = strconv.FormatInt(typedKey, 10) - case float64: - // Stolen from go-yaml to use the same conversion to string as - // the go-yaml library uses to convert float to string when - // Marshaling. - s := strconv.FormatFloat(typedKey, 'g', -1, 32) - switch s { - case "+Inf": - s = ".inf" - case "-Inf": - s = "-.inf" - case "NaN": - s = ".nan" - } - keyString = s - case bool: - if typedKey { - keyString = "true" - } else { - keyString = "false" - } - default: - return nil, fmt.Errorf("Unsupported map key of type: %s, key: %+#v, value: %+#v", - reflect.TypeOf(k), k, v) - } - - // jsonTarget should be a struct or a map. If it's a struct, find - // the field it's going to map to and pass its reflect.Value. If - // it's a map, find the element type of the map and pass the - // reflect.Value created from that type. If it's neither, just pass - // nil - JSON conversion will error for us if it's a real issue. - if jsonTarget != nil { - t := *jsonTarget - if t.Kind() == reflect.Struct { - keyBytes := []byte(keyString) - // Find the field that the JSON library would use. - var f *field - fields := cachedTypeFields(t.Type()) - for i := range fields { - ff := &fields[i] - if bytes.Equal(ff.nameBytes, keyBytes) { - f = ff - break - } - // Do case-insensitive comparison. - if f == nil && ff.equalFold(ff.nameBytes, keyBytes) { - f = ff - } - } - if f != nil { - // Find the reflect.Value of the most preferential - // struct field. - jtf := t.Field(f.index[0]) - strMap[keyString], err = convertToJSONableObject(v, &jtf) - if err != nil { - return nil, err - } - continue - } - } else if t.Kind() == reflect.Map { - // Create a zero value of the map's element type to use as - // the JSON target. - jtv := reflect.Zero(t.Type().Elem()) - strMap[keyString], err = convertToJSONableObject(v, &jtv) - if err != nil { - return nil, err - } - continue - } - } - strMap[keyString], err = convertToJSONableObject(v, nil) - if err != nil { - return nil, err - } - } - return strMap, nil - case []interface{}: - // We need to recurse into arrays in case there are any - // map[interface{}]interface{}'s inside and to convert any - // numbers to strings. - - // If jsonTarget is a slice (which it really should be), find the - // thing it's going to map to. If it's not a slice, just pass nil - // - JSON conversion will error for us if it's a real issue. - var jsonSliceElemValue *reflect.Value - if jsonTarget != nil { - t := *jsonTarget - if t.Kind() == reflect.Slice { - // By default slices point to nil, but we need a reflect.Value - // pointing to a value of the slice type, so we create one here. - ev := reflect.Indirect(reflect.New(t.Type().Elem())) - jsonSliceElemValue = &ev - } - } - - // Make and use a new array. - arr := make([]interface{}, len(typedYAMLObj)) - for i, v := range typedYAMLObj { - arr[i], err = convertToJSONableObject(v, jsonSliceElemValue) - if err != nil { - return nil, err - } - } - return arr, nil - default: - // If the target type is a string and the YAML type is a number, - // convert the YAML type to a string. - if jsonTarget != nil && (*jsonTarget).Kind() == reflect.String { - // Based on my reading of go-yaml, it may return int, int64, - // float64, or uint64. - var s string - switch typedVal := typedYAMLObj.(type) { - case int: - s = strconv.FormatInt(int64(typedVal), 10) - case int64: - s = strconv.FormatInt(typedVal, 10) - case float64: - s = strconv.FormatFloat(typedVal, 'g', -1, 32) - case uint64: - s = strconv.FormatUint(typedVal, 10) - case bool: - if typedVal { - s = "true" - } else { - s = "false" - } - } - if len(s) > 0 { - yamlObj = interface{}(s) - } - } - return yamlObj, nil - } - - return nil, nil -} diff --git a/vendor/github.com/jaypipes/ghw/.get-go-packages.sh b/vendor/github.com/jaypipes/ghw/.get-go-packages.sh deleted file mode 100644 index 382782f8a1..0000000000 --- a/vendor/github.com/jaypipes/ghw/.get-go-packages.sh +++ /dev/null @@ -1,3 +0,0 @@ -#! /bin/sh - -export GO_PACKAGES=$(go list ./... | grep -v /vendor/) diff --git a/vendor/github.com/jaypipes/ghw/.gitignore b/vendor/github.com/jaypipes/ghw/.gitignore deleted file mode 100644 index 34d0d840aa..0000000000 --- a/vendor/github.com/jaypipes/ghw/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -vendor/ -coverage*.* -*~ diff --git a/vendor/github.com/jaypipes/ghw/.travis.yml b/vendor/github.com/jaypipes/ghw/.travis.yml deleted file mode 100644 index 4e0286f7e2..0000000000 --- a/vendor/github.com/jaypipes/ghw/.travis.yml +++ /dev/null @@ -1,25 +0,0 @@ -language: go -go: "1.13" -# Using sudo triggers a real virtual machine as opposed to a container, which -# allows ghw to actually determine things like host memory or block storage... -sudo: required -script: - - source ./.get-go-packages.sh - - go test -v $GO_PACKAGES - - go run cmd/ghwc/main.go -env: - - GHW_TESTING_SKIP_GPU=1 - - GO111MODULE="on" -matrix: - include: - - os: linux - go: "1.13" - - os: linux - go: "1.14.x" - - # Tests that ghw builds on MacOSX (even though there is currently only - # support for block devices) - #- os: osx - # go: "1.13" - #- os: osx - # go: "1.14.x" diff --git a/vendor/github.com/jaypipes/ghw/COPYING b/vendor/github.com/jaypipes/ghw/COPYING deleted file mode 100644 index 68c771a099..0000000000 --- a/vendor/github.com/jaypipes/ghw/COPYING +++ /dev/null @@ -1,176 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - diff --git a/vendor/github.com/jaypipes/ghw/Dockerfile b/vendor/github.com/jaypipes/ghw/Dockerfile deleted file mode 100644 index a488b3820d..0000000000 --- a/vendor/github.com/jaypipes/ghw/Dockerfile +++ /dev/null @@ -1,26 +0,0 @@ -FROM golang:1.13-stretch as builder -WORKDIR /go/src/github.com/jaypipes/ghw - -# Force the go compiler to use modules. -ENV GO111MODULE=on -ENV GOPROXY=direct - -# go.mod and go.sum go into their own layers. -COPY go.mod . -COPY go.sum . - -# This ensures `go mod download` happens only when go.mod and go.sum change. -RUN go mod download - -COPY . . - -RUN CGO_ENABLED=0 go build -o ghwc ./cmd/ghwc/ - -FROM alpine:3.7 -RUN apk add --no-cache ethtool - -WORKDIR /bin - -COPY --from=builder /go/src/github.com/jaypipes/ghw/ghwc /bin - -CMD ghwc diff --git a/vendor/github.com/jaypipes/ghw/Makefile b/vendor/github.com/jaypipes/ghw/Makefile deleted file mode 100644 index c7e0db4020..0000000000 --- a/vendor/github.com/jaypipes/ghw/Makefile +++ /dev/null @@ -1,39 +0,0 @@ -VENDOR := vendor -PKGS := $(shell go list ./... | grep -v /$(VENDOR)/) -SRC = $(shell find . -type f -name '*.go' -not -path "*/$(VENDOR)/*") -BIN_DIR := $(GOPATH)/bin -GOMETALINTER := $(BIN_DIR)/gometalinter - -.PHONY: test -test: vet - go test $(PKGS) - -$(GOMETALINTER): - go get -u github.com/alecthomas/gometalinter - $(GOMETALINTER) --install &> /dev/null - -.PHONY: lint -lint: $(GOMETALINTER) - $(GOMETALINTER) ./... --vendor - -.PHONY: fmt -fmt: - @echo "Running gofmt on all sources..." - @gofmt -s -l -w $(SRC) - -.PHONY: fmtcheck -fmtcheck: - @bash -c "diff -u <(echo -n) <(gofmt -d $(SRC))" - -.PHONY: vet -vet: - go vet $(PKGS) - -.PHONY: cover -cover: - $(shell [ -e coverage.out ] && rm coverage.out) - @echo "mode: count" > coverage-all.out - $(foreach pkg,$(PKGS),\ - go test -coverprofile=coverage.out -covermode=count $(pkg);\ - tail -n +2 coverage.out >> coverage-all.out;) - go tool cover -html=coverage-all.out -o=coverage-all.html diff --git a/vendor/github.com/jaypipes/ghw/README.md b/vendor/github.com/jaypipes/ghw/README.md deleted file mode 100644 index 6b4f37c1c1..0000000000 --- a/vendor/github.com/jaypipes/ghw/README.md +++ /dev/null @@ -1,1318 +0,0 @@ -# `ghw` - Golang HardWare discovery/inspection library [![Build Status](https://travis-ci.org/jaypipes/ghw.svg?branch=master)](https://travis-ci.org/jaypipes/ghw) -![ghw mascot](images/ghw-gopher.png) -

-`ghw` is a small Golang library providing hardware inspection and discovery -for Linux and Windows. There currently exists partial support for MacOSX. - -## Design Principles - -* No root privileges needed for discovery - - `ghw` goes the extra mile to be useful without root priveleges. We query for - host hardware information as directly as possible without relying on shellouts - to programs like `dmidecode` that require root privileges to execute. - - Elevated privileges are indeed required to query for some information, but - `ghw` will never error out if blocked from reading that information. Instead, - `ghw` will print a warning message about the information that could not be - retrieved. You may disable these warning messages with `GHW_DISABLE_WARNINGS` - environment variable. - -* Well-documented code and plenty of example code - - The code itself should be well-documented with lots of usage - examples. - -* Interfaces should be consistent across modules - - Each module in the library should be structured in a consistent fashion, and - the structs returned by various library functions should have consistent - attribute and method names. - -## Inspecting != Monitoring - -`ghw` is a tool for gathering information about your hardware's **capacity** -and **capabilities**. - -It is important to point out that `ghw` does **NOT** report information that is -temporary or variable. It is **NOT** a system monitor nor is it an appropriate -tool for gathering data points for metrics that change over time. If you are -looking for a system that tracks usage of CPU, memory, network I/O or disk I/O, -there are plenty of great open source tools that do this! Check out the -[Prometheus project](https://prometheus.io/) for a great example. - -## Usage - -You can use the functions in `ghw` to determine various hardware-related -information about the host computer: - -* [Memory](#memory) -* [CPU](#cpu) -* [Block storage](#block-storage) -* [Topology](#topology) -* [Network](#network) -* [PCI](#pci) -* [GPU](#gpu) -* [Chassis](#chassis) -* [BIOS](#bios) -* [Baseboard](#baseboard) -* [Product](#product) -* [YAML and JSON serialization](#serialization) - -### Overriding the root mountpoint `ghw` uses - -The default root mountpoint that `ghw` uses when looking for information about -the host system is `/`. So, for example, when looking up CPU information on a -Linux system, `ghw.CPU()` will use the path `/proc/cpuinfo`. - -If you are calling `ghw` from a system that has an alternate root mountpoint, -you can either set the `GHW_CHROOT` environment variable to that alternate -path, or call the module constructor function with the `ghw.WithChroot()` -modifier. - -For example, if you are executing from within an application container that has -bind-mounted the root host filesystem to the mount point `/host`, you would set -`GHW_CHROOT` to `/host` so that `ghw` can find `/proc/cpuinfo` at -`/host/proc/cpuinfo`. - -Alternately, you can use the `ghw.WithChroot()` function like so: - -```go -cpu, err := ghw.CPU(ghw.WithChroot("/host")) -``` - -### Consuming snapshots - -You can make `ghw` read from snapshots (created with `ghw-snapshot`) using -environment variables or programmatically. -Please check `SNAPSHOT.md` to learn more about how ghw creates and consumes -snapshots. - -The environment variable `GHW_SNAPSHOT_PATH` let users specify a snapshot -that `ghw` will automatically consume. All the needed chroot changes will be -automatically performed. By default, the snapshot is unpacked on a temporary -directory managed by `ghw`, and cleaned up when no longer needed, avoiding -leftovers. - -The rest of the environment variables are relevant iff `GHW_SNAPSHOT_PATH` is given. -`GHW_SNAPSHOT_ROOT` let users specify the directory -on which the snapshot should be unpacked. This moves the ownership of that -directory from `ghw` to users. For this reason, `ghw` will *not* clean up automatically -the content unpacked in `GHW_SNAPSHOT_ROOT`. - -`GHW_SNAPSHOT_EXCLUSIVE` is relevant iff `GHW_SNAPSHOT_ROOT` is given. -Set it to any value to toggle it on. This tells `ghw` that the directory is meant -only to contain the given snapshot, thus `ghw` will *not* attempt to unpack it -(and will go ahead silently!) unless the directory is empty. -You can use both `GHW_SNAPSHOT_ROOT` and `GHW_SNAPSHOT_EXCLUSIVE` to make sure -`ghw` unpacks the snapshot only once regardless of how many `ghw` packages -(e.g. cpu, memory) access it. - -Set `GHW_SNAPSHOT_PRESERVE` to any value to enable it. If set, `ghw` will *not* -clean up the unpacked snapshot once done, leaving it into the system. - -```go -cpu, err := ghw.CPU(ghw.WithSnapshot(ghw.SnapshotOptions{ - Path: "/path/to/linux-amd64-d4771ed3300339bc75f856be09fc6430.tar.gz", -})) - - -myRoot := "/my/safe/directory" -cpu, err := ghw.CPU(ghw.WithSnapshot(ghw.SnapshotOptions{ - Path: "/path/to/linux-amd64-d4771ed3300339bc75f856be09fc6430.tar.gz", - Root: &myRoot, -})) - -myOtherRoot := "/my/other/safe/directory" -cpu, err := ghw.CPU(ghw.WithSnapshot(ghw.SnapshotOptions{ - Path: "/path/to/linux-amd64-d4771ed3300339bc75f856be09fc6430.tar.gz", - Root: &myOtherRoot, - Exclusive: true, -})) -``` - -### Creating snapshots - -You can create ghw snapshots in two ways. -You can just consume the `ghw-snapshot` tool, or you can create them programmatically -from your golang code. We explore now the latter case. - -Snapshotting takes two phases: -1. clone the relevant pseudofiles/pseudodirectories into a temporary tree - This tree is usually deleted once the packing is successful. -2. pack the cloned tree into a tar.gz - -```go - -import ( - "fmt" - "io/ioutil" - "os" - - "github.com/jaypipes/ghw/pkg/snapshot" -) - -// ... - -scratchDir, err := ioutil.TempDir("", "ghw-snapshot-*") -if err != nil { - fmt.Printf("Error creating clone directory: %v", err) -} -defer os.RemoveAll(scratchDir) - -// this step clones all the files and directories ghw cares about -if err := snapshot.CloneTreeInto(scratchDir); err != nil { - fmt.Printf("error cloning into %q: %v", scratchDir, err) -} - -// optionally, you may add extra content into your snapshot. -// ghw will ignore the extra content. -// Glob patterns like `filepath.Glob` are supported. -fileSpecs := []string{ - "/proc/cmdline", -} - -// options allows the client code to optionally deference symlinks, or copy -// them into the cloned tree as symlinks -var opts *snapshot.CopyFileOptions -if err := snapshot.CopyFilesInto(fileSpecs, scratchDir, opts); err != nil { - fmt.Printf("error cloning extra files into %q: %v", scratchDir, err) -} - -// automates the creation of the gzipped tarball out of the given tree. -if err := snapshot.PackFrom("my-snapshot.tgz", scratchDir); err != nil { - fmt.Printf("error packing %q into %q: %v", scratchDir, *output, err) -} -``` - -### Disabling warning messages - -When `ghw` isn't able to retrieve some information, it may print certain -warning messages to `stderr`. To disable these warnings, simply set the -`GHW_DISABLE_WARNINGS` environs variable: - -``` -$ ghwc memory -WARNING: -Could not determine total physical bytes of memory. This may -be due to the host being a virtual machine or container with no -/var/log/syslog file, or the current user may not have necessary -privileges to read the syslog. We are falling back to setting the -total physical amount of memory to the total usable amount of memory -memory (24GB physical, 24GB usable) -``` - -``` -$ GHW_DISABLE_WARNINGS=1 ghwc memory -memory (24GB physical, 24GB usable) -``` - -You can disable warning programmatically using the `WithDisableWarnings` option: - -```go - -import ( - "github.com/jaypipes/ghw" -) - -mem, err := ghw.Memory(ghw.WithDisableWarnings()) -``` - -`WithDisableWarnings` is a alias for the `WithNullAlerter` option, which in turn -leverages the more general `Alerter` feature of ghw. - -You may supply a `Alerter` to ghw to redirect all the warnings there, like -logger objects (see for example golang's stdlib `log.Logger`). -`Alerter` is in fact the minimal logging interface `ghw needs. -To learn more, please check the `option.Alerter` interface and the `ghw.WithAlerter()` -function. - -### Memory - -Information about the host computer's memory can be retrieved using the -`ghw.Memory()` function which returns a pointer to a `ghw.MemoryInfo` struct. - -The `ghw.MemoryInfo` struct contains three fields: - -* `ghw.MemoryInfo.TotalPhysicalBytes` contains the amount of physical memory on - the host -* `ghw.MemoryInfo.TotalUsableBytes` contains the amount of memory the - system can actually use. Usable memory accounts for things like the kernel's - resident memory size and some reserved system bits -* `ghw.MemoryInfo.SupportedPageSizes` is an array of integers representing the - size, in bytes, of memory pages the system supports -* `ghw.MemoryInfo.Modules` is an array of pointers to `ghw.MemoryModule` - structs, one for each physical [DIMM](https://en.wikipedia.org/wiki/DIMM). - Currently, this information is only included on Windows, with Linux support - [planned](https://github.com/jaypipes/ghw/pull/171#issuecomment-597082409). - -```go -package main - -import ( - "fmt" - - "github.com/jaypipes/ghw" -) - -func main() { - memory, err := ghw.Memory() - if err != nil { - fmt.Printf("Error getting memory info: %v", err) - } - - fmt.Println(memory.String()) -} -``` - -Example output from my personal workstation: - -``` -memory (24GB physical, 24GB usable) -``` - -#### Physical versus Usable Memory - -There has been [some](https://github.com/jaypipes/ghw/pull/171) -[confusion](https://github.com/jaypipes/ghw/issues/183) regarding the -difference between the total physical bytes versus total usable bytes of -memory. - -Some of this confusion has been due to a misunderstanding of the term "usable". -As mentioned [above](#inspection!=monitoring), `ghw` does inspection of the -system's capacity. - -A host computer has two capacities when it comes to RAM. The first capacity is -the amount of RAM that is contained in all memory banks (DIMMs) that are -attached to the motherboard. `ghw.MemoryInfo.TotalPhysicalBytes` refers to this -first capacity. - -There is a (usually small) amount of RAM that is consumed by the bootloader -before the operating system is started (booted). Once the bootloader has booted -the operating system, the amount of RAM that may be used by the operating -system and its applications is fixed. `ghw.MemoryInfo.TotalUsableBytes` refers -to this second capacity. - -You can determine the amount of RAM that the bootloader used (that is not made -available to the operating system) by subtracting -`ghw.MemoryInfo.TotalUsableBytes` from `ghw.MemoryInfo.TotalPhysicalBytes`: - -```go -package main - -import ( - "fmt" - - "github.com/jaypipes/ghw" -) - -func main() { - memory, err := ghw.Memory() - if err != nil { - fmt.Printf("Error getting memory info: %v", err) - } - - phys := memory.TotalPhysicalBytes - usable := memory.TotalUsableBytes - - fmt.Printf("The bootloader consumes %d bytes of RAM\n", phys - usable) -} -``` - -Example output from my personal workstation booted into a Windows10 operating -system with a Linux GRUB bootloader: - -``` -The bootloader consumes 3832720 bytes of RAM -``` - -### CPU - -The `ghw.CPU()` function returns a `ghw.CPUInfo` struct that contains -information about the CPUs on the host system. - -`ghw.CPUInfo` contains the following fields: - -* `ghw.CPUInfo.TotalCores` has the total number of physical cores the host - system contains -* `ghw.CPUInfo.TotalThreads` has the total number of hardware threads the - host system contains -* `ghw.CPUInfo.Processors` is an array of `ghw.Processor` structs, one for each - physical processor package contained in the host - -Each `ghw.Processor` struct contains a number of fields: - -* `ghw.Processor.ID` is the physical processor `uint32` ID according to the - system -* `ghw.Processor.NumCores` is the number of physical cores in the processor - package -* `ghw.Processor.NumThreads` is the number of hardware threads in the processor - package -* `ghw.Processor.Vendor` is a string containing the vendor name -* `ghw.Processor.Model` is a string containing the vendor's model name -* `ghw.Processor.Capabilities` is an array of strings indicating the features - the processor has enabled -* `ghw.Processor.Cores` is an array of `ghw.ProcessorCore` structs that are - packed onto this physical processor - -A `ghw.ProcessorCore` has the following fields: - -* `ghw.ProcessorCore.ID` is the `uint32` identifier that the host gave this - core. Note that this does *not* necessarily equate to a zero-based index of - the core within a physical package. For example, the core IDs for an Intel Core - i7 are 0, 1, 2, 8, 9, and 10 -* `ghw.ProcessorCore.Index` is the zero-based index of the core on the physical - processor package -* `ghw.ProcessorCore.NumThreads` is the number of hardware threads associated - with the core -* `ghw.ProcessorCore.LogicalProcessors` is an array of logical processor IDs - assigned to any processing unit for the core - -```go -package main - -import ( - "fmt" - "math" - "strings" - - "github.com/jaypipes/ghw" -) - -func main() { - cpu, err := ghw.CPU() - if err != nil { - fmt.Printf("Error getting CPU info: %v", err) - } - - fmt.Printf("%v\n", cpu) - - for _, proc := range cpu.Processors { - fmt.Printf(" %v\n", proc) - for _, core := range proc.Cores { - fmt.Printf(" %v\n", core) - } - if len(proc.Capabilities) > 0 { - // pretty-print the (large) block of capability strings into rows - // of 6 capability strings - rows := int(math.Ceil(float64(len(proc.Capabilities)) / float64(6))) - for row := 1; row < rows; row = row + 1 { - rowStart := (row * 6) - 1 - rowEnd := int(math.Min(float64(rowStart+6), float64(len(proc.Capabilities)))) - rowElems := proc.Capabilities[rowStart:rowEnd] - capStr := strings.Join(rowElems, " ") - if row == 1 { - fmt.Printf(" capabilities: [%s\n", capStr) - } else if rowEnd < len(proc.Capabilities) { - fmt.Printf(" %s\n", capStr) - } else { - fmt.Printf(" %s]\n", capStr) - } - } - } - } -} -``` - -Example output from my personal workstation: - -``` -cpu (1 physical package, 6 cores, 12 hardware threads) - physical package #0 (6 cores, 12 hardware threads) - processor core #0 (2 threads), logical processors [0 6] - processor core #1 (2 threads), logical processors [1 7] - processor core #2 (2 threads), logical processors [2 8] - processor core #3 (2 threads), logical processors [3 9] - processor core #4 (2 threads), logical processors [4 10] - processor core #5 (2 threads), logical processors [5 11] - capabilities: [msr pae mce cx8 apic sep - mtrr pge mca cmov pat pse36 - clflush dts acpi mmx fxsr sse - sse2 ss ht tm pbe syscall - nx pdpe1gb rdtscp lm constant_tsc arch_perfmon - pebs bts rep_good nopl xtopology nonstop_tsc - cpuid aperfmperf pni pclmulqdq dtes64 monitor - ds_cpl vmx est tm2 ssse3 cx16 - xtpr pdcm pcid sse4_1 sse4_2 popcnt - aes lahf_lm pti retpoline tpr_shadow vnmi - flexpriority ept vpid dtherm ida arat] -``` - -### Block storage - -Information about the host computer's local block storage is returned from the -`ghw.Block()` function. This function returns a pointer to a `ghw.BlockInfo` -struct. - -The `ghw.BlockInfo` struct contains two fields: - -* `ghw.BlockInfo.TotalPhysicalBytes` contains the amount of physical block - storage on the host -* `ghw.BlockInfo.Disks` is an array of pointers to `ghw.Disk` structs, one for - each disk drive found by the system - -Each `ghw.Disk` struct contains the following fields: - -* `ghw.Disk.Name` contains a string with the short name of the disk, e.g. "sda" -* `ghw.Disk.SizeBytes` contains the amount of storage the disk provides -* `ghw.Disk.PhysicalBlockSizeBytes` contains the size of the physical blocks - used on the disk, in bytes -* `ghw.Disk.IsRemovable` contains a boolean indicating if the disk drive is - removable -* `ghw.Disk.DriveType` is the type of drive. It is of type `ghw.DriveType` - which has a `ghw.DriveType.String()` method that can be called to return a - string representation of the bus. This string will be "HDD", "FDD", "ODD", - or "SSD", which correspond to a hard disk drive (rotational), floppy drive, - optical (CD/DVD) drive and solid-state drive. -* `ghw.Disk.StorageController` is the type of storage controller/drive. It is - of type `ghw.StorageController` which has a `ghw.StorageController.String()` - method that can be called to return a string representation of the bus. This - string will be "SCSI", "IDE", "virtio", "MMC", or "NVMe" -* `ghw.Disk.NUMANodeID` is the numeric index of the NUMA node this disk is - local to, or -1 -* `ghw.Disk.Vendor` contains a string with the name of the hardware vendor for - the disk drive -* `ghw.Disk.Model` contains a string with the vendor-assigned disk model name -* `ghw.Disk.SerialNumber` contains a string with the disk's serial number -* `ghw.Disk.WWN` contains a string with the disk's - [World Wide Name](https://en.wikipedia.org/wiki/World_Wide_Name) -* `ghw.Disk.Partitions` contains an array of pointers to `ghw.Partition` - structs, one for each partition on the disk - -Each `ghw.Partition` struct contains these fields: - -* `ghw.Partition.Name` contains a string with the short name of the partition, - e.g. "sda1" -* `ghw.Partition.SizeBytes` contains the amount of storage the partition - provides -* `ghw.Partition.MountPoint` contains a string with the partition's mount - point, or "" if no mount point was discovered -* `ghw.Partition.Type` contains a string indicated the filesystem type for the - partition, or "" if the system could not determine the type -* `ghw.Partition.IsReadOnly` is a bool indicating the partition is read-only -* `ghw.Partition.Disk` is a pointer to the `ghw.Disk` object associated with - the partition. This will be `nil` if the `ghw.Partition` struct was returned - by the `ghw.DiskPartitions()` library function. -* `ghw.Partition.UUID` is a string containing the volume UUID on Linux, the - partition UUID on MacOS and nothing on Windows. - -```go -package main - -import ( - "fmt" - - "github.com/jaypipes/ghw" -) - -func main() { - block, err := ghw.Block() - if err != nil { - fmt.Printf("Error getting block storage info: %v", err) - } - - fmt.Printf("%v\n", block) - - for _, disk := range block.Disks { - fmt.Printf(" %v\n", disk) - for _, part := range disk.Partitions { - fmt.Printf(" %v\n", part) - } - } -} -``` - -Example output from my personal workstation: - -``` -block storage (1 disk, 2TB physical storage) - sda HDD (2TB) SCSI [@pci-0000:04:00.0-scsi-0:1:0:0 (node #0)] vendor=LSI model=Logical_Volume serial=600508e000000000f8253aac9a1abd0c WWN=0x600508e000000000f8253aac9a1abd0c - /dev/sda1 (100MB) - /dev/sda2 (187GB) - /dev/sda3 (449MB) - /dev/sda4 (1KB) - /dev/sda5 (15GB) - /dev/sda6 (2TB) [ext4] mounted@/ -``` - -> Note that `ghw` looks in the udev runtime database for some information. If -> you are using `ghw` in a container, remember to bind mount `/dev/disk` and -> `/run` into your container, otherwise `ghw` won't be able to query the udev -> DB or sysfs paths for information. - -### Topology - -> **NOTE**: Topology support is currently Linux-only. Windows support is -> [planned](https://github.com/jaypipes/ghw/issues/166). - -Information about the host computer's architecture (NUMA vs. SMP), the host's -node layout and processor caches can be retrieved from the `ghw.Topology()` -function. This function returns a pointer to a `ghw.TopologyInfo` struct. - -The `ghw.TopologyInfo` struct contains two fields: - -* `ghw.TopologyInfo.Architecture` contains an enum with the value `ghw.NUMA` or - `ghw.SMP` depending on what the topology of the system is -* `ghw.TopologyInfo.Nodes` is an array of pointers to `ghw.TopologyNode` - structs, one for each topology node (typically physical processor package) - found by the system - -Each `ghw.TopologyNode` struct contains the following fields: - -* `ghw.TopologyNode.ID` is the system's `uint32` identifier for the node -* `ghw.TopologyNode.Cores` is an array of pointers to `ghw.ProcessorCore` structs that - are contained in this node -* `ghw.TopologyNode.Caches` is an array of pointers to `ghw.MemoryCache` structs that - represent the low-level caches associated with processors and cores on the - system -* `ghw.TopologyNode.Distance` is an array of distances between NUMA nodes as reported - by the system. - -See above in the [CPU](#cpu) section for information about the -`ghw.ProcessorCore` struct and how to use and query it. - -Each `ghw.MemoryCache` struct contains the following fields: - -* `ghw.MemoryCache.Type` is an enum that contains one of `ghw.DATA`, - `ghw.INSTRUCTION` or `ghw.UNIFIED` depending on whether the cache stores CPU - instructions, program data, or both -* `ghw.MemoryCache.Level` is a positive integer indicating how close the cache - is to the processor -* `ghw.MemoryCache.SizeBytes` is an integer containing the number of bytes the - cache can contain -* `ghw.MemoryCache.LogicalProcessors` is an array of integers representing the - logical processors that use the cache - -```go -package main - -import ( - "fmt" - - "github.com/jaypipes/ghw" -) - -func main() { - topology, err := ghw.Topology() - if err != nil { - fmt.Printf("Error getting topology info: %v", err) - } - - fmt.Printf("%v\n", topology) - - for _, node := range topology.Nodes { - fmt.Printf(" %v\n", node) - for _, cache := range node.Caches { - fmt.Printf(" %v\n", cache) - } - } -} -``` - -Example output from my personal workstation: - -``` -topology SMP (1 nodes) - node #0 (6 cores) - L1i cache (32 KB) shared with logical processors: 3,9 - L1i cache (32 KB) shared with logical processors: 2,8 - L1i cache (32 KB) shared with logical processors: 11,5 - L1i cache (32 KB) shared with logical processors: 10,4 - L1i cache (32 KB) shared with logical processors: 0,6 - L1i cache (32 KB) shared with logical processors: 1,7 - L1d cache (32 KB) shared with logical processors: 11,5 - L1d cache (32 KB) shared with logical processors: 10,4 - L1d cache (32 KB) shared with logical processors: 3,9 - L1d cache (32 KB) shared with logical processors: 1,7 - L1d cache (32 KB) shared with logical processors: 0,6 - L1d cache (32 KB) shared with logical processors: 2,8 - L2 cache (256 KB) shared with logical processors: 2,8 - L2 cache (256 KB) shared with logical processors: 3,9 - L2 cache (256 KB) shared with logical processors: 0,6 - L2 cache (256 KB) shared with logical processors: 10,4 - L2 cache (256 KB) shared with logical processors: 1,7 - L2 cache (256 KB) shared with logical processors: 11,5 - L3 cache (12288 KB) shared with logical processors: 0,1,10,11,2,3,4,5,6,7,8,9 -``` - -### Network - -Information about the host computer's networking hardware is returned from the -`ghw.Network()` function. This function returns a pointer to a -`ghw.NetworkInfo` struct. - -The `ghw.NetworkInfo` struct contains one field: - -* `ghw.NetworkInfo.NICs` is an array of pointers to `ghw.NIC` structs, one - for each network interface controller found for the systen - -Each `ghw.NIC` struct contains the following fields: - -* `ghw.NIC.Name` is the system's identifier for the NIC -* `ghw.NIC.MacAddress` is the MAC address for the NIC, if any -* `ghw.NIC.IsVirtual` is a boolean indicating if the NIC is a virtualized - device -* `ghw.NIC.Capabilities` is an array of pointers to `ghw.NICCapability` structs - that can describe the things the NIC supports. These capabilities match the - returned values from the `ethtool -k ` call on Linux -* `ghw.NIC.PCIAddress` is the PCI device address of the device backing the NIC. - this is not-nil only if the backing device is indeed a PCI device; more backing - devices (e.g. USB) will be added in future versions. - -The `ghw.NICCapability` struct contains the following fields: - -* `ghw.NICCapability.Name` is the string name of the capability (e.g. - "tcp-segmentation-offload") -* `ghw.NICCapability.IsEnabled` is a boolean indicating whether the capability - is currently enabled/active on the NIC -* `ghw.NICCapability.CanEnable` is a boolean indicating whether the capability - may be enabled - -```go -package main - -import ( - "fmt" - - "github.com/jaypipes/ghw" -) - -func main() { - net, err := ghw.Network() - if err != nil { - fmt.Printf("Error getting network info: %v", err) - } - - fmt.Printf("%v\n", net) - - for _, nic := range net.NICs { - fmt.Printf(" %v\n", nic) - - enabledCaps := make([]int, 0) - for x, cap := range nic.Capabilities { - if cap.IsEnabled { - enabledCaps = append(enabledCaps, x) - } - } - if len(enabledCaps) > 0 { - fmt.Printf(" enabled capabilities:\n") - for _, x := range enabledCaps { - fmt.Printf(" - %s\n", nic.Capabilities[x].Name) - } - } - } -} -``` - -Example output from my personal laptop: - -``` -net (3 NICs) - docker0 - enabled capabilities: - - tx-checksumming - - tx-checksum-ip-generic - - scatter-gather - - tx-scatter-gather - - tx-scatter-gather-fraglist - - tcp-segmentation-offload - - tx-tcp-segmentation - - tx-tcp-ecn-segmentation - - tx-tcp-mangleid-segmentation - - tx-tcp6-segmentation - - udp-fragmentation-offload - - generic-segmentation-offload - - generic-receive-offload - - tx-vlan-offload - - highdma - - tx-lockless - - netns-local - - tx-gso-robust - - tx-fcoe-segmentation - - tx-gre-segmentation - - tx-gre-csum-segmentation - - tx-ipxip4-segmentation - - tx-ipxip6-segmentation - - tx-udp_tnl-segmentation - - tx-udp_tnl-csum-segmentation - - tx-gso-partial - - tx-sctp-segmentation - - tx-esp-segmentation - - tx-vlan-stag-hw-insert - enp58s0f1 - enabled capabilities: - - rx-checksumming - - generic-receive-offload - - rx-vlan-offload - - tx-vlan-offload - - highdma - wlp59s0 - enabled capabilities: - - scatter-gather - - tx-scatter-gather - - generic-segmentation-offload - - generic-receive-offload - - highdma - - netns-local -``` - -### PCI - -`ghw` contains a PCI database inspection and querying facility that allows -developers to not only gather information about devices on a local PCI bus but -also query for information about hardware device classes, vendor and product -information. - -**NOTE**: Parsing of the PCI-IDS file database is provided by the separate -[github.com/jaypipes/pcidb library](http://github.com/jaypipes/pcidb). You can -read that library's README for more information about the various structs that -are exposed on the `ghw.PCIInfo` struct. - -The `ghw.PCI()` function returns a `ghw.PCIInfo` struct. The `ghw.PCIInfo` -struct contains a number of fields that may be queried for PCI information: - -* `ghw.PCIInfo.Devices` is a slice of pointers to `ghw.PCIDevice` structs that - describe the PCI devices on the host system -* `ghw.PCIInfo.Classes` is a map, keyed by the PCI class ID (a hex-encoded - string) of pointers to `pcidb.Class` structs, one for each class of PCI - device known to `ghw` - (**DEPRECATED**, will be removed in `ghw` `v1.0`. Use the - `github.com/jaypipes/pcidb` library for exploring PCI database information) -* `ghw.PCIInfo.Vendors` is a map, keyed by the PCI vendor ID (a hex-encoded - string) of pointers to `pcidb.Vendor` structs, one for each PCI vendor - known to `ghw` - (**DEPRECATED**, will be removed in `ghw` `v1.0`. Use the - `github.com/jaypipes/pcidb` library for exploring PCI database information) -* `ghw.PCIInfo.Products` is a map, keyed by the PCI product ID (a hex-encoded - string) of pointers to `pcidb.Product` structs, one for each PCI product - known to `ghw` - (**DEPRECATED**, will be removed in `ghw` `v1.0`. Use the - `github.com/jaypipes/pcidb` library for exploring PCI database information) - -**NOTE**: PCI products are often referred to by their "device ID". We use -the term "product ID" in `ghw` because it more accurately reflects what the -identifier is for: a specific product line produced by the vendor. - -The `ghw.PCIDevice` struct has the following fields: - -* `ghw.PCIDevice.Vendor` is a pointer to a `pcidb.Vendor` struct that - describes the device's primary vendor. This will always be non-nil. -* `ghw.PCIDevice.Product` is a pointer to a `pcidb.Product` struct that - describes the device's primary product. This will always be non-nil. -* `ghw.PCIDevice.Subsystem` is a pointer to a `pcidb.Product` struct that - describes the device's secondary/sub-product. This will always be non-nil. -* `ghw.PCIDevice.Class` is a pointer to a `pcidb.Class` struct that - describes the device's class. This will always be non-nil. -* `ghw.PCIDevice.Subclass` is a pointer to a `pcidb.Subclass` struct - that describes the device's subclass. This will always be non-nil. -* `ghw.PCIDevice.ProgrammingInterface` is a pointer to a - `pcidb.ProgrammingInterface` struct that describes the device subclass' - programming interface. This will always be non-nil. - -The `ghw.PCIAddress` (which is an alias for the `ghw.pci.address.Address` -struct) contains the PCI address fields. It has a `ghw.PCIAddress.String()` -method that returns the canonical Domain:Bus:Slot.Function ([D]BSF) -representation of this Address - -#### Finding a PCI device by PCI address - -In addition to the above information, the `ghw.PCIInfo` struct has the -following method: - -* `ghw.PCIInfo.GetDevice(address string)` - -The following code snippet shows how to call the `ghw.PCIInfo.ListDevices()` -method and output a simple list of PCI address and vendor/product information: - -```go -package main - -import ( - "fmt" - - "github.com/jaypipes/ghw" -) - -func main() { - pci, err := ghw.PCI() - if err != nil { - fmt.Printf("Error getting PCI info: %v", err) - } - fmt.Printf("host PCI devices:\n") - fmt.Println("====================================================") - - for _, device := range pci.Devices { - vendor := device.Vendor - vendorName := vendor.Name - if len(vendor.Name) > 20 { - vendorName = string([]byte(vendorName)[0:17]) + "..." - } - product := device.Product - productName := product.Name - if len(product.Name) > 40 { - productName = string([]byte(productName)[0:37]) + "..." - } - fmt.Printf("%-12s\t%-20s\t%-40s\n", device.Address, vendorName, productName) - } -} -``` - -on my local workstation the output of the above looks like the following: - -``` -host PCI devices: -==================================================== -0000:00:00.0 Intel Corporation 5520/5500/X58 I/O Hub to ESI Port -0000:00:01.0 Intel Corporation 5520/5500/X58 I/O Hub PCI Express Roo... -0000:00:02.0 Intel Corporation 5520/5500/X58 I/O Hub PCI Express Roo... -0000:00:03.0 Intel Corporation 5520/5500/X58 I/O Hub PCI Express Roo... -0000:00:07.0 Intel Corporation 5520/5500/X58 I/O Hub PCI Express Roo... -0000:00:10.0 Intel Corporation 7500/5520/5500/X58 Physical and Link ... -0000:00:10.1 Intel Corporation 7500/5520/5500/X58 Routing and Protoc... -0000:00:14.0 Intel Corporation 7500/5520/5500/X58 I/O Hub System Man... -0000:00:14.1 Intel Corporation 7500/5520/5500/X58 I/O Hub GPIO and S... -0000:00:14.2 Intel Corporation 7500/5520/5500/X58 I/O Hub Control St... -0000:00:14.3 Intel Corporation 7500/5520/5500/X58 I/O Hub Throttle R... -0000:00:19.0 Intel Corporation 82567LF-2 Gigabit Network Connection -0000:00:1a.0 Intel Corporation 82801JI (ICH10 Family) USB UHCI Contr... -0000:00:1a.1 Intel Corporation 82801JI (ICH10 Family) USB UHCI Contr... -0000:00:1a.2 Intel Corporation 82801JI (ICH10 Family) USB UHCI Contr... -0000:00:1a.7 Intel Corporation 82801JI (ICH10 Family) USB2 EHCI Cont... -0000:00:1b.0 Intel Corporation 82801JI (ICH10 Family) HD Audio Contr... -0000:00:1c.0 Intel Corporation 82801JI (ICH10 Family) PCI Express Ro... -0000:00:1c.1 Intel Corporation 82801JI (ICH10 Family) PCI Express Po... -0000:00:1c.4 Intel Corporation 82801JI (ICH10 Family) PCI Express Ro... -0000:00:1d.0 Intel Corporation 82801JI (ICH10 Family) USB UHCI Contr... -0000:00:1d.1 Intel Corporation 82801JI (ICH10 Family) USB UHCI Contr... -0000:00:1d.2 Intel Corporation 82801JI (ICH10 Family) USB UHCI Contr... -0000:00:1d.7 Intel Corporation 82801JI (ICH10 Family) USB2 EHCI Cont... -0000:00:1e.0 Intel Corporation 82801 PCI Bridge -0000:00:1f.0 Intel Corporation 82801JIR (ICH10R) LPC Interface Contr... -0000:00:1f.2 Intel Corporation 82801JI (ICH10 Family) SATA AHCI Cont... -0000:00:1f.3 Intel Corporation 82801JI (ICH10 Family) SMBus Controller -0000:01:00.0 NEC Corporation uPD720200 USB 3.0 Host Controller -0000:02:00.0 Marvell Technolog... 88SE9123 PCIe SATA 6.0 Gb/s controller -0000:02:00.1 Marvell Technolog... 88SE912x IDE Controller -0000:03:00.0 NVIDIA Corporation GP107 [GeForce GTX 1050 Ti] -0000:03:00.1 NVIDIA Corporation UNKNOWN -0000:04:00.0 LSI Logic / Symbi... SAS2004 PCI-Express Fusion-MPT SAS-2 ... -0000:06:00.0 Qualcomm Atheros AR5418 Wireless Network Adapter [AR50... -0000:08:03.0 LSI Corporation FW322/323 [TrueFire] 1394a Controller -0000:3f:00.0 Intel Corporation UNKNOWN -0000:3f:00.1 Intel Corporation Xeon 5600 Series QuickPath Architectu... -0000:3f:02.0 Intel Corporation Xeon 5600 Series QPI Link 0 -0000:3f:02.1 Intel Corporation Xeon 5600 Series QPI Physical 0 -0000:3f:02.2 Intel Corporation Xeon 5600 Series Mirror Port Link 0 -0000:3f:02.3 Intel Corporation Xeon 5600 Series Mirror Port Link 1 -0000:3f:03.0 Intel Corporation Xeon 5600 Series Integrated Memory Co... -0000:3f:03.1 Intel Corporation Xeon 5600 Series Integrated Memory Co... -0000:3f:03.4 Intel Corporation Xeon 5600 Series Integrated Memory Co... -0000:3f:04.0 Intel Corporation Xeon 5600 Series Integrated Memory Co... -0000:3f:04.1 Intel Corporation Xeon 5600 Series Integrated Memory Co... -0000:3f:04.2 Intel Corporation Xeon 5600 Series Integrated Memory Co... -0000:3f:04.3 Intel Corporation Xeon 5600 Series Integrated Memory Co... -0000:3f:05.0 Intel Corporation Xeon 5600 Series Integrated Memory Co... -0000:3f:05.1 Intel Corporation Xeon 5600 Series Integrated Memory Co... -0000:3f:05.2 Intel Corporation Xeon 5600 Series Integrated Memory Co... -0000:3f:05.3 Intel Corporation Xeon 5600 Series Integrated Memory Co... -0000:3f:06.0 Intel Corporation Xeon 5600 Series Integrated Memory Co... -0000:3f:06.1 Intel Corporation Xeon 5600 Series Integrated Memory Co... -0000:3f:06.2 Intel Corporation Xeon 5600 Series Integrated Memory Co... -0000:3f:06.3 Intel Corporation Xeon 5600 Series Integrated Memory Co... -``` - -The following code snippet shows how to call the `ghw.PCIInfo.GetDevice()` -method and use its returned `ghw.PCIDevice` struct pointer: - -```go -package main - -import ( - "fmt" - "os" - - "github.com/jaypipes/ghw" -) - -func main() { - pci, err := ghw.PCI() - if err != nil { - fmt.Printf("Error getting PCI info: %v", err) - } - - addr := "0000:00:00.0" - if len(os.Args) == 2 { - addr = os.Args[1] - } - fmt.Printf("PCI device information for %s\n", addr) - fmt.Println("====================================================") - deviceInfo := pci.GetDevice(addr) - if deviceInfo == nil { - fmt.Printf("could not retrieve PCI device information for %s\n", addr) - return - } - - vendor := deviceInfo.Vendor - fmt.Printf("Vendor: %s [%s]\n", vendor.Name, vendor.ID) - product := deviceInfo.Product - fmt.Printf("Product: %s [%s]\n", product.Name, product.ID) - subsystem := deviceInfo.Subsystem - subvendor := pci.Vendors[subsystem.VendorID] - subvendorName := "UNKNOWN" - if subvendor != nil { - subvendorName = subvendor.Name - } - fmt.Printf("Subsystem: %s [%s] (Subvendor: %s)\n", subsystem.Name, subsystem.ID, subvendorName) - class := deviceInfo.Class - fmt.Printf("Class: %s [%s]\n", class.Name, class.ID) - subclass := deviceInfo.Subclass - fmt.Printf("Subclass: %s [%s]\n", subclass.Name, subclass.ID) - progIface := deviceInfo.ProgrammingInterface - fmt.Printf("Programming Interface: %s [%s]\n", progIface.Name, progIface.ID) -} -``` - -Here's a sample output from my local workstation: - -``` -PCI device information for 0000:03:00.0 -==================================================== -Vendor: NVIDIA Corporation [10de] -Product: GP107 [GeForce GTX 1050 Ti] [1c82] -Subsystem: UNKNOWN [8613] (Subvendor: ASUSTeK Computer Inc.) -Class: Display controller [03] -Subclass: VGA compatible controller [00] -Programming Interface: VGA controller [00] -``` - -### GPU - -Information about the host computer's graphics hardware is returned from the -`ghw.GPU()` function. This function returns a pointer to a `ghw.GPUInfo` -struct. - -The `ghw.GPUInfo` struct contains one field: - -* `ghw.GPUInfo.GraphicCards` is an array of pointers to `ghw.GraphicsCard` - structs, one for each graphics card found for the systen - -Each `ghw.GraphicsCard` struct contains the following fields: - -* `ghw.GraphicsCard.Index` is the system's numeric zero-based index for the - card on the bus -* `ghw.GraphicsCard.Address` is the PCI address for the graphics card -* `ghw.GraphicsCard.DeviceInfo` is a pointer to a `ghw.PCIDevice` struct - describing the graphics card. This may be `nil` if no PCI device information - could be determined for the card. -* `ghw.GraphicsCard.Node` is an pointer to a `ghw.TopologyNode` struct that the - GPU/graphics card is affined to. On non-NUMA systems, this will always be - `nil`. - -```go -package main - -import ( - "fmt" - - "github.com/jaypipes/ghw" -) - -func main() { - gpu, err := ghw.GPU() - if err != nil { - fmt.Printf("Error getting GPU info: %v", err) - } - - fmt.Printf("%v\n", gpu) - - for _, card := range gpu.GraphicsCards { - fmt.Printf(" %v\n", card) - } -} -``` - -Example output from my personal workstation: - -``` -gpu (1 graphics card) - card #0 @0000:03:00.0 -> class: 'Display controller' vendor: 'NVIDIA Corporation' product: 'GP107 [GeForce GTX 1050 Ti]' -``` - -**NOTE**: You can [read more](#pci) about the fields of the `ghw.PCIDevice` -struct if you'd like to dig deeper into PCI subsystem and programming interface -information - -**NOTE**: You can [read more](#topology) about the fields of the -`ghw.TopologyNode` struct if you'd like to dig deeper into the NUMA/topology -subsystem - -### Chassis - -The host's chassis information is accessible with the `ghw.Chassis()` function. This -function returns a pointer to a `ghw.ChassisInfo` struct. - -The `ghw.ChassisInfo` struct contains multiple fields: - -* `ghw.ChassisInfo.AssetTag` is a string with the chassis asset tag -* `ghw.ChassisInfo.SerialNumber` is a string with the chassis serial number -* `ghw.ChassisInfo.Type` is a string with the chassis type *code* -* `ghw.ChassisInfo.TypeDescription` is a string with a description of the chassis type -* `ghw.ChassisInfo.Vendor` is a string with the chassis vendor -* `ghw.ChassisInfo.Version` is a string with the chassis version - -**NOTE**: These fields are often missing for non-server hardware. Don't be -surprised to see empty string or "None" values. - -```go -package main - -import ( - "fmt" - - "github.com/jaypipes/ghw" -) - -func main() { - chassis, err := ghw.Chassis() - if err != nil { - fmt.Printf("Error getting chassis info: %v", err) - } - - fmt.Printf("%v\n", chassis) -} -``` - -Example output from my personal workstation: - -``` -chassis type=Desktop vendor=System76 version=thelio-r1 -``` - -**NOTE**: Some of the values such as serial numbers are shown as unknown because -the Linux kernel by default disallows access to those fields if you're not running -as root. They will be populated if it runs as root or otherwise you may see warnings -like the following: - -``` -WARNING: Unable to read chassis_serial: open /sys/class/dmi/id/chassis_serial: permission denied -``` - -You can ignore them or use the [Disabling warning messages](#disabling-warning-messages) -feature to quiet things down. - -### BIOS - -The host's basis input/output system (BIOS) information is accessible with the `ghw.BIOS()` function. This -function returns a pointer to a `ghw.BIOSInfo` struct. - -The `ghw.BIOSInfo` struct contains multiple fields: - -* `ghw.BIOSInfo.Vendor` is a string with the BIOS vendor -* `ghw.BIOSInfo.Version` is a string with the BIOS version -* `ghw.BIOSInfo.Date` is a string with the date the BIOS was flashed/created - -```go -package main - -import ( - "fmt" - - "github.com/jaypipes/ghw" -) - -func main() { - bios, err := ghw.BIOS() - if err != nil { - fmt.Printf("Error getting BIOS info: %v", err) - } - - fmt.Printf("%v\n", bios) -} -``` - -Example output from my personal workstation: - -``` -bios vendor=System76 version=F2 Z5 date=11/14/2018 -``` - -### Baseboard - -The host's baseboard information is accessible with the `ghw.Baseboard()` function. This -function returns a pointer to a `ghw.BaseboardInfo` struct. - -The `ghw.BaseboardInfo` struct contains multiple fields: - -* `ghw.BaseboardInfo.AssetTag` is a string with the baseboard asset tag -* `ghw.BaseboardInfo.SerialNumber` is a string with the baseboard serial number -* `ghw.BaseboardInfo.Vendor` is a string with the baseboard vendor -* `ghw.BaseboardInfo.Product` is a string with the baseboard name on Linux and - Product on Windows -* `ghw.BaseboardInfo.Version` is a string with the baseboard version - -**NOTE**: These fields are often missing for non-server hardware. Don't be -surprised to see empty string or "None" values. - -```go -package main - -import ( - "fmt" - - "github.com/jaypipes/ghw" -) - -func main() { - baseboard, err := ghw.Baseboard() - if err != nil { - fmt.Printf("Error getting baseboard info: %v", err) - } - - fmt.Printf("%v\n", baseboard) -} -``` - -Example output from my personal workstation: - -``` -baseboard vendor=System76 version=thelio-r1 -``` - -**NOTE**: Some of the values such as serial numbers are shown as unknown because -the Linux kernel by default disallows access to those fields if you're not running -as root. They will be populated if it runs as root or otherwise you may see warnings -like the following: - -``` -WARNING: Unable to read board_serial: open /sys/class/dmi/id/board_serial: permission denied -``` - -You can ignore them or use the [Disabling warning messages](#disabling-warning-messages) -feature to quiet things down. - -### Product - -The host's product information is accessible with the `ghw.Product()` function. This -function returns a pointer to a `ghw.ProductInfo` struct. - -The `ghw.ProductInfo` struct contains multiple fields: - -* `ghw.ProductInfo.Family` is a string describing the product family -* `ghw.ProductInfo.Name` is a string with the product name -* `ghw.ProductInfo.SerialNumber` is a string with the product serial number -* `ghw.ProductInfo.UUID` is a string with the product UUID -* `ghw.ProductInfo.SKU` is a string with the product stock unit identifier (SKU) -* `ghw.ProductInfo.Vendor` is a string with the product vendor -* `ghw.ProductInfo.Version` is a string with the product version - -**NOTE**: These fields are often missing for non-server hardware. Don't be -surprised to see empty string, "Default string" or "None" values. - -```go -package main - -import ( - "fmt" - - "github.com/jaypipes/ghw" -) - -func main() { - product, err := ghw.Product() - if err != nil { - fmt.Printf("Error getting product info: %v", err) - } - - fmt.Printf("%v\n", product) -} -``` - -Example output from my personal workstation: - -``` -product family=Default string name=Thelio vendor=System76 sku=Default string version=thelio-r1 -``` - -**NOTE**: Some of the values such as serial numbers are shown as unknown because -the Linux kernel by default disallows access to those fields if you're not running -as root. They will be populated if it runs as root or otherwise you may see warnings -like the following: - -``` -WARNING: Unable to read product_serial: open /sys/class/dmi/id/product_serial: permission denied -``` - -You can ignore them or use the [Disabling warning messages](#disabling-warning-messages) -feature to quiet things down. - -## Serialization - -All of the `ghw` `XXXInfo` structs -- e.g. `ghw.CPUInfo` -- have two methods -for producing a serialized JSON or YAML string representation of the contained -information: - -* `JSONString()` returns a string containing the information serialized into - JSON. It accepts a single boolean parameter indicating whether to use - indentation when outputting the string -* `YAMLString()` returns a string containing the information serialized into - YAML - -```go -package main - -import ( - "fmt" - - "github.com/jaypipes/ghw" -) - -func main() { - mem, err := ghw.Memory() - if err != nil { - fmt.Printf("Error getting memory info: %v", err) - } - - fmt.Printf("%s", mem.YAMLString()) -} -``` - -the above example code prints the following out on my local workstation: - -``` -memory: - supported_page_sizes: - - 1073741824 - - 2097152 - total_physical_bytes: 25263415296 - total_usable_bytes: 25263415296 -``` - -## Calling external programs - -By default ghw may call external programs, for example `ethtool`, to learn about hardware capabilities. -In some rare circumstances it may be useful to opt out from this behaviour and rely only on the data -provided by pseudo-filesystems, like sysfs. -The most common use case is when we want to consume a snapshot from ghw. In these cases the information -provided by tools will be most likely inconsistent with the data from the snapshot - they will run on -a different host! -To prevent ghw from calling external tools, set the environs variable `GHW_DISABLE_TOOLS` to any value, -or, programmatically, check the `WithDisableTools` function. -The default behaviour of ghw is to call external tools when available. - -## Developers - -Contributions to `ghw` are welcomed! Fork the repo on GitHub and submit a pull -request with your proposed changes. Or, feel free to log an issue for a feature -request or bug report. - -### Running tests - -You can run unit tests easily using the `make test` command, like so: - - -``` -[jaypipes@uberbox ghw]$ make test -go test github.com/jaypipes/ghw github.com/jaypipes/ghw/cmd/ghwc -ok github.com/jaypipes/ghw 0.084s -? github.com/jaypipes/ghw/cmd/ghwc [no test files] -``` diff --git a/vendor/github.com/jaypipes/ghw/SNAPSHOT.md b/vendor/github.com/jaypipes/ghw/SNAPSHOT.md deleted file mode 100644 index 696a3ea635..0000000000 --- a/vendor/github.com/jaypipes/ghw/SNAPSHOT.md +++ /dev/null @@ -1,45 +0,0 @@ -# ghw snapshots - -For ghw, snapshots are partial clones of the `/proc`, `/sys` (et. al.) subtrees copied from arbitrary -machines, which ghw can consume later. "partial" is because the snapshot doesn't need to contain a -complete copy of all the filesystem subtree (that is doable but inpractical). It only needs to contain -the paths ghw cares about. The snapshot concept was introduced [to make ghw easier to test](https://github.com/jaypipes/ghw/issues/66). - -## Create and consume snapshot - -The recommended way to create snapshots for ghw is to use the `ghw-snapshot` tool. -This tool is maintained by the ghw authors, and snapshots created with this tool are guaranteed to work. - -To consume the ghw snapshots, please check the `README.md` document. - -## Snapshot design and definitions - -The remainder of this document will describe how a snapshot looks like and provides rationale for all the major design decisions. -Even though this document aims to provide all the necessary information to understand how ghw creates snapshots and what you should -expect, we recommend to check also the [project issues](https://github.com/jaypipes/ghw/issues) and the `git` history to have the full picture. - -### Scope - -ghw supports snapshots only on linux platforms. This restriction may be lifted in future releases. -Snapshots must be consumable in the following supported ways: - -1. (way 1) from docker (or podman), mounting them as volumes. See `hack/run-against-snapshot.sh` -2. (way 2) using the environment variables `GHW_SNAPSHOT_*`. See `README.md` for the full documentation. - -Other combinations are possible, but are unsupported and may stop working any time. -You should depend only on the supported ways to consume snapshots. - -### Snapshot content constraints - -Stemming from the use cases, the snapshot content must have the following properties: - -0. (constraint 0) MUST contain the same information as live system (obviously). Whatever you learn from a live system, you MUST be able to learn from a snapshot. -1. (constraint 1) MUST NOT require any post processing before it is consumable besides, obviously, unpacking the `.tar.gz` on the right directory - and pointing ghw to that directory. -2. (constraint 2) MUST NOT require any special handling nor special code path in ghw. From ghw perspective running against a live system or against a snapshot should be completely transparent. -3. (constraint 3) MUST contain only data - no executable code is allowed ever. This makes snapshots trivially safe to share and consume. -4. (constraint 4) MUST NOT contain any personally-identifiable data. Data gathered into a snapshot is for testing and troubleshooting purposes and should be safe to send to troubleshooters to analyze. - -It must be noted that trivially cloning subtrees from `/proc` and `/sys` and creating a tarball out of them doesn't work -because both pseudo filesystems make use of symlinks, and [docker doesn't really play nice with symlinks](https://github.com/jaypipes/ghw/commit/f8ffd4d24e62eb9017511f072ccf51f13d4a3399). -This conflcits with (way 1) above. - diff --git a/vendor/github.com/jaypipes/ghw/alias.go b/vendor/github.com/jaypipes/ghw/alias.go deleted file mode 100644 index 66b4f2b956..0000000000 --- a/vendor/github.com/jaypipes/ghw/alias.go +++ /dev/null @@ -1,148 +0,0 @@ -// -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package ghw - -import ( - "github.com/jaypipes/ghw/pkg/baseboard" - "github.com/jaypipes/ghw/pkg/bios" - "github.com/jaypipes/ghw/pkg/block" - "github.com/jaypipes/ghw/pkg/chassis" - "github.com/jaypipes/ghw/pkg/cpu" - "github.com/jaypipes/ghw/pkg/gpu" - "github.com/jaypipes/ghw/pkg/memory" - "github.com/jaypipes/ghw/pkg/net" - "github.com/jaypipes/ghw/pkg/option" - "github.com/jaypipes/ghw/pkg/pci" - pciaddress "github.com/jaypipes/ghw/pkg/pci/address" - "github.com/jaypipes/ghw/pkg/product" - "github.com/jaypipes/ghw/pkg/topology" -) - -type WithOption = option.Option - -var ( - WithChroot = option.WithChroot - WithSnapshot = option.WithSnapshot - WithAlterter = option.WithAlerter - WithNullAlterter = option.WithNullAlerter - // match the existing environ variable to minimize surprises - WithDisableWarnings = option.WithNullAlerter - WithDisableTools = option.WithDisableTools -) - -type SnapshotOptions = option.SnapshotOptions - -type CPUInfo = cpu.Info - -var ( - CPU = cpu.New -) - -type MemoryInfo = memory.Info -type MemoryCacheType = memory.CacheType -type MemoryModule = memory.Module - -const ( - MEMORY_CACHE_TYPE_UNIFIED = memory.CACHE_TYPE_UNIFIED - MEMORY_CACHE_TYPE_INSTRUCTION = memory.CACHE_TYPE_INSTRUCTION - MEMORY_CACHE_TYPE_DATA = memory.CACHE_TYPE_DATA -) - -var ( - Memory = memory.New -) - -type BlockInfo = block.Info -type Disk = block.Disk -type Partition = block.Partition - -var ( - Block = block.New -) - -type DriveType = block.DriveType - -const ( - DRIVE_TYPE_UNKNOWN = block.DRIVE_TYPE_UNKNOWN - DRIVE_TYPE_HDD = block.DRIVE_TYPE_HDD - DRIVE_TYPE_FDD = block.DRIVE_TYPE_FDD - DRIVE_TYPE_ODD = block.DRIVE_TYPE_ODD - DRIVE_TYPE_SSD = block.DRIVE_TYPE_SSD -) - -type StorageController = block.StorageController - -const ( - STORAGE_CONTROLLER_UNKNOWN = block.STORAGE_CONTROLLER_UNKNOWN - STORAGE_CONTROLLER_IDE = block.STORAGE_CONTROLLER_IDE - STORAGE_CONTROLLER_SCSI = block.STORAGE_CONTROLLER_SCSI - STORAGE_CONTROLLER_NVME = block.STORAGE_CONTROLLER_NVME - STORAGE_CONTROLLER_VIRTIO = block.STORAGE_CONTROLLER_VIRTIO - STORAGE_CONTROLLER_MMC = block.STORAGE_CONTROLLER_MMC -) - -type NetworkInfo = net.Info -type NIC = net.NIC -type NICCapability = net.NICCapability - -var ( - Network = net.New -) - -type BIOSInfo = bios.Info - -var ( - BIOS = bios.New -) - -type ChassisInfo = chassis.Info - -var ( - Chassis = chassis.New -) - -type BaseboardInfo = baseboard.Info - -var ( - Baseboard = baseboard.New -) - -type TopologyInfo = topology.Info -type TopologyNode = topology.Node - -var ( - Topology = topology.New -) - -type Architecture = topology.Architecture - -const ( - ARCHITECTURE_SMP = topology.ARCHITECTURE_SMP - ARCHITECTURE_NUMA = topology.ARCHITECTURE_NUMA -) - -type PCIInfo = pci.Info -type PCIAddress = pciaddress.Address -type PCIDevice = pci.Device - -var ( - PCI = pci.New - PCIAddressFromString = pciaddress.FromString -) - -type ProductInfo = product.Info - -var ( - Product = product.New -) - -type GPUInfo = gpu.Info -type GraphicsCard = gpu.GraphicsCard - -var ( - GPU = gpu.New -) diff --git a/vendor/github.com/jaypipes/ghw/doc.go b/vendor/github.com/jaypipes/ghw/doc.go deleted file mode 100644 index 9ae0c30ae0..0000000000 --- a/vendor/github.com/jaypipes/ghw/doc.go +++ /dev/null @@ -1,314 +0,0 @@ -// -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -/* - package ghw can determine various hardware-related - information about the host computer: - - * Memory - * CPU - * Block storage - * Topology - * Network - * PCI - * GPU - - Memory - - Information about the host computer's memory can be retrieved using the - Memory function which returns a pointer to a MemoryInfo struct. - - package main - - import ( - "fmt" - - "github.com/jaypipes/ghw" - ) - - func main() { - memory, err := ghw.Memory() - if err != nil { - fmt.Printf("Error getting memory info: %v", err) - } - - fmt.Println(memory.String()) - } - - CPU - - The CPU function returns a CPUInfo struct that contains information about - the CPUs on the host system. - - package main - - import ( - "fmt" - "math" - "strings" - - "github.com/jaypipes/ghw" - ) - - func main() { - cpu, err := ghw.CPU() - if err != nil { - fmt.Printf("Error getting CPU info: %v", err) - } - - fmt.Printf("%v\n", cpu) - - for _, proc := range cpu.Processors { - fmt.Printf(" %v\n", proc) - for _, core := range proc.Cores { - fmt.Printf(" %v\n", core) - } - if len(proc.Capabilities) > 0 { - // pretty-print the (large) block of capability strings into rows - // of 6 capability strings - rows := int(math.Ceil(float64(len(proc.Capabilities)) / float64(6))) - for row := 1; row < rows; row = row + 1 { - rowStart := (row * 6) - 1 - rowEnd := int(math.Min(float64(rowStart+6), float64(len(proc.Capabilities)))) - rowElems := proc.Capabilities[rowStart:rowEnd] - capStr := strings.Join(rowElems, " ") - if row == 1 { - fmt.Printf(" capabilities: [%s\n", capStr) - } else if rowEnd < len(proc.Capabilities) { - fmt.Printf(" %s\n", capStr) - } else { - fmt.Printf(" %s]\n", capStr) - } - } - } - } - } - - Block storage - - Information about the host computer's local block storage is returned from - the Block function. This function returns a pointer to a BlockInfo struct. - - package main - - import ( - "fmt" - - "github.com/jaypipes/ghw" - ) - - func main() { - block, err := ghw.Block() - if err != nil { - fmt.Printf("Error getting block storage info: %v", err) - } - - fmt.Printf("%v\n", block) - - for _, disk := range block.Disks { - fmt.Printf(" %v\n", disk) - for _, part := range disk.Partitions { - fmt.Printf(" %v\n", part) - } - } - } - - Topology - - Information about the host computer's architecture (NUMA vs. SMP), the - host's node layout and processor caches can be retrieved from the Topology - function. This function returns a pointer to a TopologyInfo struct. - - package main - - import ( - "fmt" - - "github.com/jaypipes/ghw" - ) - - func main() { - topology, err := ghw.Topology() - if err != nil { - fmt.Printf("Error getting topology info: %v", err) - } - - fmt.Printf("%v\n", topology) - - for _, node := range topology.Nodes { - fmt.Printf(" %v\n", node) - for _, cache := range node.Caches { - fmt.Printf(" %v\n", cache) - } - } - } - - Network - - Information about the host computer's networking hardware is returned from - the Network function. This function returns a pointer to a NetworkInfo - struct. - - package main - - import ( - "fmt" - - "github.com/jaypipes/ghw" - ) - - func main() { - net, err := ghw.Network() - if err != nil { - fmt.Printf("Error getting network info: %v", err) - } - - fmt.Printf("%v\n", net) - - for _, nic := range net.NICs { - fmt.Printf(" %v\n", nic) - - enabledCaps := make([]int, 0) - for x, cap := range nic.Capabilities { - if cap.IsEnabled { - enabledCaps = append(enabledCaps, x) - } - } - if len(enabledCaps) > 0 { - fmt.Printf(" enabled capabilities:\n") - for _, x := range enabledCaps { - fmt.Printf(" - %s\n", nic.Capabilities[x].Name) - } - } - } - } - - PCI - - ghw contains a PCI database inspection and querying facility that allows - developers to not only gather information about devices on a local PCI bus - but also query for information about hardware device classes, vendor and - product information. - - **NOTE**: Parsing of the PCI-IDS file database is provided by the separate - http://github.com/jaypipes/pcidb library. You can read that library's - README for more information about the various structs that are exposed on - the PCIInfo struct. - - PCIInfo.ListDevices is used to iterate over a host's PCI devices: - - package main - - import ( - "fmt" - - "github.com/jaypipes/ghw" - ) - - func main() { - pci, err := ghw.PCI() - if err != nil { - fmt.Printf("Error getting PCI info: %v", err) - } - fmt.Printf("host PCI devices:\n") - fmt.Println("====================================================") - devices := pci.ListDevices() - if len(devices) == 0 { - fmt.Printf("error: could not retrieve PCI devices\n") - return - } - - for _, device := range devices { - vendor := device.Vendor - vendorName := vendor.Name - if len(vendor.Name) > 20 { - vendorName = string([]byte(vendorName)[0:17]) + "..." - } - product := device.Product - productName := product.Name - if len(product.Name) > 40 { - productName = string([]byte(productName)[0:37]) + "..." - } - fmt.Printf("%-12s\t%-20s\t%-40s\n", device.Address, vendorName, productName) - } - } - - The following code snippet shows how to call the PCIInfo.GetDevice method - and use its returned PCIDevice struct pointer: - - package main - - import ( - "fmt" - "os" - - "github.com/jaypipes/ghw" - ) - - func main() { - pci, err := ghw.PCI() - if err != nil { - fmt.Printf("Error getting PCI info: %v", err) - } - - addr := "0000:00:00.0" - if len(os.Args) == 2 { - addr = os.Args[1] - } - fmt.Printf("PCI device information for %s\n", addr) - fmt.Println("====================================================") - deviceInfo := pci.GetDevice(addr) - if deviceInfo == nil { - fmt.Printf("could not retrieve PCI device information for %s\n", addr) - return - } - - vendor := deviceInfo.Vendor - fmt.Printf("Vendor: %s [%s]\n", vendor.Name, vendor.ID) - product := deviceInfo.Product - fmt.Printf("Product: %s [%s]\n", product.Name, product.ID) - subsystem := deviceInfo.Subsystem - subvendor := pci.Vendors[subsystem.VendorID] - subvendorName := "UNKNOWN" - if subvendor != nil { - subvendorName = subvendor.Name - } - fmt.Printf("Subsystem: %s [%s] (Subvendor: %s)\n", subsystem.Name, subsystem.ID, subvendorName) - class := deviceInfo.Class - fmt.Printf("Class: %s [%s]\n", class.Name, class.ID) - subclass := deviceInfo.Subclass - fmt.Printf("Subclass: %s [%s]\n", subclass.Name, subclass.ID) - progIface := deviceInfo.ProgrammingInterface - fmt.Printf("Programming Interface: %s [%s]\n", progIface.Name, progIface.ID) - } - - GPU - - Information about the host computer's graphics hardware is returned from - the GPU function. This function returns a pointer to a GPUInfo struct. - - package main - - import ( - "fmt" - - "github.com/jaypipes/ghw" - ) - - func main() { - gpu, err := ghw.GPU() - if err != nil { - fmt.Printf("Error getting GPU info: %v", err) - } - - fmt.Printf("%v\n", gpu) - - for _, card := range gpu.GraphicsCards { - fmt.Printf(" %v\n", card) - } - } -*/ -package ghw diff --git a/vendor/github.com/jaypipes/ghw/host.go b/vendor/github.com/jaypipes/ghw/host.go deleted file mode 100644 index 5d82a53a14..0000000000 --- a/vendor/github.com/jaypipes/ghw/host.go +++ /dev/null @@ -1,139 +0,0 @@ -// -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package ghw - -import ( - "fmt" - - "github.com/jaypipes/ghw/pkg/context" - - "github.com/jaypipes/ghw/pkg/baseboard" - "github.com/jaypipes/ghw/pkg/bios" - "github.com/jaypipes/ghw/pkg/block" - "github.com/jaypipes/ghw/pkg/chassis" - "github.com/jaypipes/ghw/pkg/cpu" - "github.com/jaypipes/ghw/pkg/gpu" - "github.com/jaypipes/ghw/pkg/marshal" - "github.com/jaypipes/ghw/pkg/memory" - "github.com/jaypipes/ghw/pkg/net" - "github.com/jaypipes/ghw/pkg/pci" - "github.com/jaypipes/ghw/pkg/product" - "github.com/jaypipes/ghw/pkg/topology" -) - -// HostInfo is a wrapper struct containing information about the host system's -// memory, block storage, CPU, etc -type HostInfo struct { - ctx *context.Context - Memory *memory.Info `json:"memory"` - Block *block.Info `json:"block"` - CPU *cpu.Info `json:"cpu"` - Topology *topology.Info `json:"topology"` - Network *net.Info `json:"network"` - GPU *gpu.Info `json:"gpu"` - Chassis *chassis.Info `json:"chassis"` - BIOS *bios.Info `json:"bios"` - Baseboard *baseboard.Info `json:"baseboard"` - Product *product.Info `json:"product"` - PCI *pci.Info `json:"pci"` -} - -// Host returns a pointer to a HostInfo struct that contains fields with -// information about the host system's CPU, memory, network devices, etc -func Host(opts ...*WithOption) (*HostInfo, error) { - ctx := context.New(opts...) - - memInfo, err := memory.New(opts...) - if err != nil { - return nil, err - } - blockInfo, err := block.New(opts...) - if err != nil { - return nil, err - } - cpuInfo, err := cpu.New(opts...) - if err != nil { - return nil, err - } - topologyInfo, err := topology.New(opts...) - if err != nil { - return nil, err - } - netInfo, err := net.New(opts...) - if err != nil { - return nil, err - } - gpuInfo, err := gpu.New(opts...) - if err != nil { - return nil, err - } - chassisInfo, err := chassis.New(opts...) - if err != nil { - return nil, err - } - biosInfo, err := bios.New(opts...) - if err != nil { - return nil, err - } - baseboardInfo, err := baseboard.New(opts...) - if err != nil { - return nil, err - } - productInfo, err := product.New(opts...) - if err != nil { - return nil, err - } - pciInfo, err := pci.New(opts...) - if err != nil { - return nil, err - } - return &HostInfo{ - ctx: ctx, - CPU: cpuInfo, - Memory: memInfo, - Block: blockInfo, - Topology: topologyInfo, - Network: netInfo, - GPU: gpuInfo, - Chassis: chassisInfo, - BIOS: biosInfo, - Baseboard: baseboardInfo, - Product: productInfo, - PCI: pciInfo, - }, nil -} - -// String returns a newline-separated output of the HostInfo's component -// structs' String-ified output -func (info *HostInfo) String() string { - return fmt.Sprintf( - "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n", - info.Block.String(), - info.CPU.String(), - info.GPU.String(), - info.Memory.String(), - info.Network.String(), - info.Topology.String(), - info.Chassis.String(), - info.BIOS.String(), - info.Baseboard.String(), - info.Product.String(), - info.PCI.String(), - ) -} - -// YAMLString returns a string with the host information formatted as YAML -// under a top-level "host:" key -func (i *HostInfo) YAMLString() string { - return marshal.SafeYAML(i.ctx, i) -} - -// JSONString returns a string with the host information formatted as JSON -// under a top-level "host:" key -func (i *HostInfo) JSONString(indent bool) string { - return marshal.SafeJSON(i.ctx, i, indent) -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/baseboard/baseboard.go b/vendor/github.com/jaypipes/ghw/pkg/baseboard/baseboard.go deleted file mode 100644 index f503194c60..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/baseboard/baseboard.go +++ /dev/null @@ -1,84 +0,0 @@ -// -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package baseboard - -import ( - "fmt" - - "github.com/jaypipes/ghw/pkg/context" - "github.com/jaypipes/ghw/pkg/marshal" - "github.com/jaypipes/ghw/pkg/option" - "github.com/jaypipes/ghw/pkg/util" -) - -// Info defines baseboard release information -type Info struct { - ctx *context.Context - AssetTag string `json:"asset_tag"` - SerialNumber string `json:"serial_number"` - Vendor string `json:"vendor"` - Version string `json:"version"` - Product string `json:"product"` -} - -func (i *Info) String() string { - vendorStr := "" - if i.Vendor != "" { - vendorStr = " vendor=" + i.Vendor - } - serialStr := "" - if i.SerialNumber != "" && i.SerialNumber != util.UNKNOWN { - serialStr = " serial=" + i.SerialNumber - } - versionStr := "" - if i.Version != "" { - versionStr = " version=" + i.Version - } - - productStr := "" - if i.Product != "" { - productStr = " product=" + i.Product - } - - res := fmt.Sprintf( - "baseboard%s%s%s%s", - vendorStr, - serialStr, - versionStr, - productStr, - ) - return res -} - -// New returns a pointer to an Info struct containing information about the -// host's baseboard -func New(opts ...*option.Option) (*Info, error) { - ctx := context.New(opts...) - info := &Info{ctx: ctx} - if err := ctx.Do(info.load); err != nil { - return nil, err - } - return info, nil -} - -// simple private struct used to encapsulate baseboard information in a top-level -// "baseboard" YAML/JSON map/object key -type baseboardPrinter struct { - Info *Info `json:"baseboard"` -} - -// YAMLString returns a string with the baseboard information formatted as YAML -// under a top-level "dmi:" key -func (info *Info) YAMLString() string { - return marshal.SafeYAML(info.ctx, baseboardPrinter{info}) -} - -// JSONString returns a string with the baseboard information formatted as JSON -// under a top-level "baseboard:" key -func (info *Info) JSONString(indent bool) string { - return marshal.SafeJSON(info.ctx, baseboardPrinter{info}, indent) -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/baseboard/baseboard_linux.go b/vendor/github.com/jaypipes/ghw/pkg/baseboard/baseboard_linux.go deleted file mode 100644 index c8c598d421..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/baseboard/baseboard_linux.go +++ /dev/null @@ -1,20 +0,0 @@ -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package baseboard - -import ( - "github.com/jaypipes/ghw/pkg/linuxdmi" -) - -func (i *Info) load() error { - i.AssetTag = linuxdmi.Item(i.ctx, "board_asset_tag") - i.SerialNumber = linuxdmi.Item(i.ctx, "board_serial") - i.Vendor = linuxdmi.Item(i.ctx, "board_vendor") - i.Version = linuxdmi.Item(i.ctx, "board_version") - i.Product = linuxdmi.Item(i.ctx, "board_name") - - return nil -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/baseboard/baseboard_stub.go b/vendor/github.com/jaypipes/ghw/pkg/baseboard/baseboard_stub.go deleted file mode 100644 index 2c83c71cdd..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/baseboard/baseboard_stub.go +++ /dev/null @@ -1,17 +0,0 @@ -// +build !linux,!windows -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package baseboard - -import ( - "runtime" - - "github.com/pkg/errors" -) - -func (i *Info) load() error { - return errors.New("baseboardFillInfo not implemented on " + runtime.GOOS) -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/baseboard/baseboard_windows.go b/vendor/github.com/jaypipes/ghw/pkg/baseboard/baseboard_windows.go deleted file mode 100644 index 0fb14fbffe..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/baseboard/baseboard_windows.go +++ /dev/null @@ -1,37 +0,0 @@ -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package baseboard - -import ( - "github.com/StackExchange/wmi" -) - -const wqlBaseboard = "SELECT Manufacturer, SerialNumber, Tag, Version, Product FROM Win32_BaseBoard" - -type win32Baseboard struct { - Manufacturer *string - SerialNumber *string - Tag *string - Version *string - Product *string -} - -func (i *Info) load() error { - // Getting data from WMI - var win32BaseboardDescriptions []win32Baseboard - if err := wmi.Query(wqlBaseboard, &win32BaseboardDescriptions); err != nil { - return err - } - if len(win32BaseboardDescriptions) > 0 { - i.AssetTag = *win32BaseboardDescriptions[0].Tag - i.SerialNumber = *win32BaseboardDescriptions[0].SerialNumber - i.Vendor = *win32BaseboardDescriptions[0].Manufacturer - i.Version = *win32BaseboardDescriptions[0].Version - i.Product = *win32BaseboardDescriptions[0].Product - } - - return nil -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/bios/bios.go b/vendor/github.com/jaypipes/ghw/pkg/bios/bios.go deleted file mode 100644 index 85a7c64b16..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/bios/bios.go +++ /dev/null @@ -1,77 +0,0 @@ -// -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package bios - -import ( - "fmt" - - "github.com/jaypipes/ghw/pkg/context" - "github.com/jaypipes/ghw/pkg/marshal" - "github.com/jaypipes/ghw/pkg/option" - "github.com/jaypipes/ghw/pkg/util" -) - -// Info defines BIOS release information -type Info struct { - ctx *context.Context - Vendor string `json:"vendor"` - Version string `json:"version"` - Date string `json:"date"` -} - -func (i *Info) String() string { - - vendorStr := "" - if i.Vendor != "" { - vendorStr = " vendor=" + i.Vendor - } - versionStr := "" - if i.Version != "" { - versionStr = " version=" + i.Version - } - dateStr := "" - if i.Date != "" && i.Date != util.UNKNOWN { - dateStr = " date=" + i.Date - } - - res := fmt.Sprintf( - "bios%s%s%s", - vendorStr, - versionStr, - dateStr, - ) - return res -} - -// New returns a pointer to a Info struct containing information -// about the host's BIOS -func New(opts ...*option.Option) (*Info, error) { - ctx := context.New(opts...) - info := &Info{ctx: ctx} - if err := ctx.Do(info.load); err != nil { - return nil, err - } - return info, nil -} - -// simple private struct used to encapsulate BIOS information in a top-level -// "bios" YAML/JSON map/object key -type biosPrinter struct { - Info *Info `json:"bios"` -} - -// YAMLString returns a string with the BIOS information formatted as YAML -// under a top-level "dmi:" key -func (info *Info) YAMLString() string { - return marshal.SafeYAML(info.ctx, biosPrinter{info}) -} - -// JSONString returns a string with the BIOS information formatted as JSON -// under a top-level "bios:" key -func (info *Info) JSONString(indent bool) string { - return marshal.SafeJSON(info.ctx, biosPrinter{info}, indent) -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/bios/bios_linux.go b/vendor/github.com/jaypipes/ghw/pkg/bios/bios_linux.go deleted file mode 100644 index 9788f4f7a1..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/bios/bios_linux.go +++ /dev/null @@ -1,16 +0,0 @@ -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package bios - -import "github.com/jaypipes/ghw/pkg/linuxdmi" - -func (i *Info) load() error { - i.Vendor = linuxdmi.Item(i.ctx, "bios_vendor") - i.Version = linuxdmi.Item(i.ctx, "bios_version") - i.Date = linuxdmi.Item(i.ctx, "bios_date") - - return nil -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/bios/bios_stub.go b/vendor/github.com/jaypipes/ghw/pkg/bios/bios_stub.go deleted file mode 100644 index 362df4c90e..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/bios/bios_stub.go +++ /dev/null @@ -1,17 +0,0 @@ -// +build !linux,!windows -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package bios - -import ( - "runtime" - - "github.com/pkg/errors" -) - -func (i *Info) load() error { - return errors.New("biosFillInfo not implemented on " + runtime.GOOS) -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/bios/bios_windows.go b/vendor/github.com/jaypipes/ghw/pkg/bios/bios_windows.go deleted file mode 100644 index 778628e9a8..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/bios/bios_windows.go +++ /dev/null @@ -1,32 +0,0 @@ -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package bios - -import ( - "github.com/StackExchange/wmi" -) - -const wqlBIOS = "SELECT InstallDate, Manufacturer, Version FROM CIM_BIOSElement" - -type win32BIOS struct { - InstallDate *string - Manufacturer *string - Version *string -} - -func (i *Info) load() error { - // Getting data from WMI - var win32BIOSDescriptions []win32BIOS - if err := wmi.Query(wqlBIOS, &win32BIOSDescriptions); err != nil { - return err - } - if len(win32BIOSDescriptions) > 0 { - i.Vendor = *win32BIOSDescriptions[0].Manufacturer - i.Version = *win32BIOSDescriptions[0].Version - i.Date = *win32BIOSDescriptions[0].InstallDate - } - return nil -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/block/block.go b/vendor/github.com/jaypipes/ghw/pkg/block/block.go deleted file mode 100644 index 7a2e4e384a..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/block/block.go +++ /dev/null @@ -1,250 +0,0 @@ -// -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package block - -import ( - "fmt" - "math" - "strings" - - "github.com/jaypipes/ghw/pkg/context" - "github.com/jaypipes/ghw/pkg/marshal" - "github.com/jaypipes/ghw/pkg/option" - "github.com/jaypipes/ghw/pkg/unitutil" - "github.com/jaypipes/ghw/pkg/util" -) - -// DriveType describes the general category of drive device -type DriveType int - -const ( - DRIVE_TYPE_UNKNOWN DriveType = iota - DRIVE_TYPE_HDD // Hard disk drive - DRIVE_TYPE_FDD // Floppy disk drive - DRIVE_TYPE_ODD // Optical disk drive - DRIVE_TYPE_SSD // Solid-state drive -) - -var ( - driveTypeString = map[DriveType]string{ - DRIVE_TYPE_UNKNOWN: "Unknown", - DRIVE_TYPE_HDD: "HDD", - DRIVE_TYPE_FDD: "FDD", - DRIVE_TYPE_ODD: "ODD", - DRIVE_TYPE_SSD: "SSD", - } -) - -func (dt DriveType) String() string { - return driveTypeString[dt] -} - -// NOTE(jaypipes): since serialized output is as "official" as we're going to -// get, let's lowercase the string output when serializing, in order to -// "normalize" the expected serialized output -func (dt DriveType) MarshalJSON() ([]byte, error) { - return []byte("\"" + strings.ToLower(dt.String()) + "\""), nil -} - -// StorageController is a category of block storage controller/driver. It -// represents more of the physical hardware interface than the storage -// protocol, which represents more of the software interface. -// -// See discussion on https://github.com/jaypipes/ghw/issues/117 -type StorageController int - -const ( - STORAGE_CONTROLLER_UNKNOWN StorageController = iota - STORAGE_CONTROLLER_IDE // Integrated Drive Electronics - STORAGE_CONTROLLER_SCSI // Small computer system interface - STORAGE_CONTROLLER_NVME // Non-volatile Memory Express - STORAGE_CONTROLLER_VIRTIO // Virtualized storage controller/driver - STORAGE_CONTROLLER_MMC // Multi-media controller (used for mobile phone storage devices) -) - -var ( - storageControllerString = map[StorageController]string{ - STORAGE_CONTROLLER_UNKNOWN: "Unknown", - STORAGE_CONTROLLER_IDE: "IDE", - STORAGE_CONTROLLER_SCSI: "SCSI", - STORAGE_CONTROLLER_NVME: "NVMe", - STORAGE_CONTROLLER_VIRTIO: "virtio", - STORAGE_CONTROLLER_MMC: "MMC", - } -) - -func (sc StorageController) String() string { - return storageControllerString[sc] -} - -// NOTE(jaypipes): since serialized output is as "official" as we're going to -// get, let's lowercase the string output when serializing, in order to -// "normalize" the expected serialized output -func (sc StorageController) MarshalJSON() ([]byte, error) { - return []byte("\"" + strings.ToLower(sc.String()) + "\""), nil -} - -// Disk describes a single disk drive on the host system. Disk drives provide -// raw block storage resources. -type Disk struct { - Name string `json:"name"` - SizeBytes uint64 `json:"size_bytes"` - PhysicalBlockSizeBytes uint64 `json:"physical_block_size_bytes"` - DriveType DriveType `json:"drive_type"` - IsRemovable bool `json:"removable"` - StorageController StorageController `json:"storage_controller"` - BusPath string `json:"bus_path"` - // TODO(jaypipes): Convert this to a TopologyNode struct pointer and then - // add to serialized output as "numa_node,omitempty" - NUMANodeID int `json:"-"` - Vendor string `json:"vendor"` - Model string `json:"model"` - SerialNumber string `json:"serial_number"` - WWN string `json:"wwn"` - Partitions []*Partition `json:"partitions"` - // TODO(jaypipes): Add PCI field for accessing PCI device information - // PCI *PCIDevice `json:"pci"` -} - -// Partition describes a logical division of a Disk. -type Partition struct { - Disk *Disk `json:"-"` - Name string `json:"name"` - Label string `json:"label"` - MountPoint string `json:"mount_point"` - SizeBytes uint64 `json:"size_bytes"` - Type string `json:"type"` - IsReadOnly bool `json:"read_only"` - UUID string `json:"uuid"` // This would be volume UUID on macOS, PartUUID on linux, empty on Windows -} - -// Info describes all disk drives and partitions in the host system. -type Info struct { - ctx *context.Context - // TODO(jaypipes): Deprecate this field and replace with TotalSizeBytes - TotalPhysicalBytes uint64 `json:"total_size_bytes"` - Disks []*Disk `json:"disks"` - Partitions []*Partition `json:"-"` -} - -// New returns a pointer to an Info struct that describes the block storage -// resources of the host system. -func New(opts ...*option.Option) (*Info, error) { - ctx := context.New(opts...) - info := &Info{ctx: ctx} - if err := ctx.Do(info.load); err != nil { - return nil, err - } - return info, nil -} - -func (i *Info) String() string { - tpbs := util.UNKNOWN - if i.TotalPhysicalBytes > 0 { - tpb := i.TotalPhysicalBytes - unit, unitStr := unitutil.AmountString(int64(tpb)) - tpb = uint64(math.Ceil(float64(tpb) / float64(unit))) - tpbs = fmt.Sprintf("%d%s", tpb, unitStr) - } - dplural := "disks" - if len(i.Disks) == 1 { - dplural = "disk" - } - return fmt.Sprintf("block storage (%d %s, %s physical storage)", - len(i.Disks), dplural, tpbs) -} - -func (d *Disk) String() string { - sizeStr := util.UNKNOWN - if d.SizeBytes > 0 { - size := d.SizeBytes - unit, unitStr := unitutil.AmountString(int64(size)) - size = uint64(math.Ceil(float64(size) / float64(unit))) - sizeStr = fmt.Sprintf("%d%s", size, unitStr) - } - atNode := "" - if d.NUMANodeID >= 0 { - atNode = fmt.Sprintf(" (node #%d)", d.NUMANodeID) - } - vendor := "" - if d.Vendor != "" { - vendor = " vendor=" + d.Vendor - } - model := "" - if d.Model != util.UNKNOWN { - model = " model=" + d.Model - } - serial := "" - if d.SerialNumber != util.UNKNOWN { - serial = " serial=" + d.SerialNumber - } - wwn := "" - if d.WWN != util.UNKNOWN { - wwn = " WWN=" + d.WWN - } - removable := "" - if d.IsRemovable { - removable = " removable=true" - } - return fmt.Sprintf( - "%s %s (%s) %s [@%s%s]%s%s%s%s%s", - d.Name, - d.DriveType.String(), - sizeStr, - d.StorageController.String(), - d.BusPath, - atNode, - vendor, - model, - serial, - wwn, - removable, - ) -} - -func (p *Partition) String() string { - typeStr := "" - if p.Type != "" { - typeStr = fmt.Sprintf("[%s]", p.Type) - } - mountStr := "" - if p.MountPoint != "" { - mountStr = fmt.Sprintf(" mounted@%s", p.MountPoint) - } - sizeStr := util.UNKNOWN - if p.SizeBytes > 0 { - size := p.SizeBytes - unit, unitStr := unitutil.AmountString(int64(size)) - size = uint64(math.Ceil(float64(size) / float64(unit))) - sizeStr = fmt.Sprintf("%d%s", size, unitStr) - } - return fmt.Sprintf( - "%s (%s) %s%s", - p.Name, - sizeStr, - typeStr, - mountStr, - ) -} - -// simple private struct used to encapsulate block information in a top-level -// "block" YAML/JSON map/object key -type blockPrinter struct { - Info *Info `json:"block" yaml:"block"` -} - -// YAMLString returns a string with the block information formatted as YAML -// under a top-level "block:" key -func (i *Info) YAMLString() string { - return marshal.SafeYAML(i.ctx, blockPrinter{i}) -} - -// JSONString returns a string with the block information formatted as JSON -// under a top-level "block:" key -func (i *Info) JSONString(indent bool) string { - return marshal.SafeJSON(i.ctx, blockPrinter{i}, indent) -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/block/block_darwin.go b/vendor/github.com/jaypipes/ghw/pkg/block/block_darwin.go deleted file mode 100644 index b3a960906a..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/block/block_darwin.go +++ /dev/null @@ -1,283 +0,0 @@ -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package block - -import ( - "fmt" - "os" - "os/exec" - "path" - "strings" - - "github.com/pkg/errors" - "howett.net/plist" -) - -type diskOrPartitionPlistNode struct { - Content string - DeviceIdentifier string - DiskUUID string - VolumeName string - VolumeUUID string - Size int64 - MountPoint string - Partitions []diskOrPartitionPlistNode - APFSVolumes []diskOrPartitionPlistNode -} - -type diskUtilListPlist struct { - AllDisks []string - AllDisksAndPartitions []diskOrPartitionPlistNode - VolumesFromDisks []string - WholeDisks []string -} - -type diskUtilInfoPlist struct { - AESHardware bool // true - Bootable bool // true - BooterDeviceIdentifier string // disk1s2 - BusProtocol string // PCI-Express - CanBeMadeBootable bool // false - CanBeMadeBootableRequiresDestroy bool // false - Content string // some-uuid-foo-bar - DeviceBlockSize int64 // 4096 - DeviceIdentifier string // disk1s1 - DeviceNode string // /dev/disk1s1 - DeviceTreePath string // IODeviceTree:/PCI0@0/RP17@1B/ANS2@0/AppleANS2Controller - DiskUUID string // some-uuid-foo-bar - Ejectable bool // false - EjectableMediaAutomaticUnderSoftwareControl bool // false - EjectableOnly bool // false - FilesystemName string // APFS - FilesystemType string // apfs - FilesystemUserVisibleName string // APFS - FreeSpace int64 // 343975677952 - GlobalPermissionsEnabled bool // true - IOKitSize int64 // 499963174912 - IORegistryEntryName string // Macintosh HD - Internal bool // true - MediaName string // - MediaType string // Generic - MountPoint string // / - ParentWholeDisk string // disk1 - PartitionMapPartition bool // false - RAIDMaster bool // false - RAIDSlice bool // false - RecoveryDeviceIdentifier string // disk1s3 - Removable bool // false - RemovableMedia bool // false - RemovableMediaOrExternalDevice bool // false - SMARTStatus string // Verified - Size int64 // 499963174912 - SolidState bool // true - SupportsGlobalPermissionsDisable bool // true - SystemImage bool // false - TotalSize int64 // 499963174912 - VolumeAllocationBlockSize int64 // 4096 - VolumeName string // Macintosh HD - VolumeSize int64 // 499963174912 - VolumeUUID string // some-uuid-foo-bar - WholeDisk bool // false - Writable bool // true - WritableMedia bool // true - WritableVolume bool // true - // also has a SMARTDeviceSpecificKeysMayVaryNotGuaranteed dict with various info - // NOTE: VolumeUUID sometimes == DiskUUID, but not always. So far Content is always a different UUID. -} - -type ioregPlist struct { - // there's a lot more than just this... - ModelNumber string `plist:"Model Number"` - SerialNumber string `plist:"Serial Number"` - VendorName string `plist:"Vendor Name"` -} - -func getDiskUtilListPlist() (*diskUtilListPlist, error) { - out, err := exec.Command("diskutil", "list", "-plist").Output() - if err != nil { - return nil, errors.Wrap(err, "diskutil list failed") - } - - var data diskUtilListPlist - if _, err := plist.Unmarshal(out, &data); err != nil { - return nil, errors.Wrap(err, "diskutil list plist unmarshal failed") - } - - return &data, nil -} - -func getDiskUtilInfoPlist(device string) (*diskUtilInfoPlist, error) { - out, err := exec.Command("diskutil", "info", "-plist", device).Output() - if err != nil { - return nil, errors.Wrapf(err, "diskutil info for %q failed", device) - } - - var data diskUtilInfoPlist - if _, err := plist.Unmarshal(out, &data); err != nil { - return nil, errors.Wrapf(err, "diskutil info plist unmarshal for %q failed", device) - } - - return &data, nil -} - -func getIoregPlist(ioDeviceTreePath string) (*ioregPlist, error) { - name := path.Base(ioDeviceTreePath) - - args := []string{ - "ioreg", - "-a", // use XML output - "-d", "1", // limit device tree output depth to root node - "-r", // root device tree at matched node - "-n", name, // match by name - } - out, err := exec.Command(args[0], args[1:]...).Output() - if err != nil { - return nil, errors.Wrapf(err, "ioreg query for %q failed", ioDeviceTreePath) - } - if out == nil || len(out) == 0 { - return nil, nil - } - - var data []ioregPlist - if _, err := plist.Unmarshal(out, &data); err != nil { - return nil, errors.Wrapf(err, "ioreg unmarshal for %q failed", ioDeviceTreePath) - } - if len(data) != 1 { - err := errors.Errorf("ioreg unmarshal resulted in %d I/O device tree nodes (expected 1)", len(data)) - return nil, err - } - - return &data[0], nil -} - -func makePartition(disk, s diskOrPartitionPlistNode, isAPFS bool) (*Partition, error) { - if s.Size < 0 { - return nil, errors.Errorf("invalid size %q of partition %q", s.Size, s.DeviceIdentifier) - } - - var partType string - if isAPFS { - partType = "APFS Volume" - } else { - partType = s.Content - } - - info, err := getDiskUtilInfoPlist(s.DeviceIdentifier) - if err != nil { - return nil, err - } - - return &Partition{ - Disk: nil, // filled in later - Name: s.DeviceIdentifier, - Label: s.VolumeName, - MountPoint: s.MountPoint, - SizeBytes: uint64(s.Size), - Type: partType, - IsReadOnly: !info.WritableVolume, - UUID: s.VolumeUUID, - }, nil -} - -// driveTypeFromPlist looks at the supplied property list struct and attempts to -// determine the disk type -func driveTypeFromPlist(infoPlist *diskUtilInfoPlist) DriveType { - dt := DRIVE_TYPE_HDD - if infoPlist.SolidState { - dt = DRIVE_TYPE_SSD - } - // TODO(jaypipes): Figure out how to determine floppy and/or CD/optical - // drive type on Mac - return dt -} - -// storageControllerFromPlist looks at the supplied property list struct and -// attempts to determine the storage controller in use for the device -func storageControllerFromPlist(infoPlist *diskUtilInfoPlist) StorageController { - sc := STORAGE_CONTROLLER_SCSI - if strings.HasSuffix(infoPlist.DeviceTreePath, "IONVMeController") { - sc = STORAGE_CONTROLLER_NVME - } - // TODO(jaypipes): I don't know if Mac even supports IDE controllers and - // the "virtio" controller is libvirt-specific - return sc -} - -func (info *Info) load() error { - listPlist, err := getDiskUtilListPlist() - if err != nil { - fmt.Fprintln(os.Stderr, err.Error()) - return err - } - - info.TotalPhysicalBytes = 0 - info.Disks = make([]*Disk, 0, len(listPlist.AllDisksAndPartitions)) - info.Partitions = []*Partition{} - - for _, disk := range listPlist.AllDisksAndPartitions { - if disk.Size < 0 { - return errors.Errorf("invalid size %q of disk %q", disk.Size, disk.DeviceIdentifier) - } - - infoPlist, err := getDiskUtilInfoPlist(disk.DeviceIdentifier) - if err != nil { - return err - } - if infoPlist.DeviceBlockSize < 0 { - return errors.Errorf("invalid block size %q of disk %q", infoPlist.DeviceBlockSize, disk.DeviceIdentifier) - } - - busPath := strings.TrimPrefix(infoPlist.DeviceTreePath, "IODeviceTree:") - - ioregPlist, err := getIoregPlist(infoPlist.DeviceTreePath) - if err != nil { - return err - } - if ioregPlist == nil { - continue - } - - // The NUMA node & WWN don't seem to be reported by any tools available by default in macOS. - diskReport := &Disk{ - Name: disk.DeviceIdentifier, - SizeBytes: uint64(disk.Size), - PhysicalBlockSizeBytes: uint64(infoPlist.DeviceBlockSize), - DriveType: driveTypeFromPlist(infoPlist), - IsRemovable: infoPlist.Removable, - StorageController: storageControllerFromPlist(infoPlist), - BusPath: busPath, - NUMANodeID: -1, - Vendor: ioregPlist.VendorName, - Model: ioregPlist.ModelNumber, - SerialNumber: ioregPlist.SerialNumber, - WWN: "", - Partitions: make([]*Partition, 0, len(disk.Partitions)+len(disk.APFSVolumes)), - } - - for _, partition := range disk.Partitions { - part, err := makePartition(disk, partition, false) - if err != nil { - return err - } - part.Disk = diskReport - diskReport.Partitions = append(diskReport.Partitions, part) - } - for _, volume := range disk.APFSVolumes { - part, err := makePartition(disk, volume, true) - if err != nil { - return err - } - part.Disk = diskReport - diskReport.Partitions = append(diskReport.Partitions, part) - } - - info.TotalPhysicalBytes += uint64(disk.Size) - info.Disks = append(info.Disks, diskReport) - info.Partitions = append(info.Partitions, diskReport.Partitions...) - } - - return nil -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/block/block_linux.go b/vendor/github.com/jaypipes/ghw/pkg/block/block_linux.go deleted file mode 100644 index 612d3b99b0..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/block/block_linux.go +++ /dev/null @@ -1,470 +0,0 @@ -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package block - -import ( - "bufio" - "io" - "io/ioutil" - "os" - "os/exec" - "path/filepath" - "strconv" - "strings" - - "github.com/jaypipes/ghw/pkg/context" - "github.com/jaypipes/ghw/pkg/linuxpath" - "github.com/jaypipes/ghw/pkg/util" -) - -const ( - sectorSize = 512 -) - -func (i *Info) load() error { - paths := linuxpath.New(i.ctx) - i.Disks = disks(i.ctx, paths) - var tpb uint64 - for _, d := range i.Disks { - tpb += d.SizeBytes - } - i.TotalPhysicalBytes = tpb - return nil -} - -func diskPhysicalBlockSizeBytes(paths *linuxpath.Paths, disk string) uint64 { - // We can find the sector size in Linux by looking at the - // /sys/block/$DEVICE/queue/physical_block_size file in sysfs - path := filepath.Join(paths.SysBlock, disk, "queue", "physical_block_size") - contents, err := ioutil.ReadFile(path) - if err != nil { - return 0 - } - size, err := strconv.ParseUint(strings.TrimSpace(string(contents)), 10, 64) - if err != nil { - return 0 - } - return size -} - -func diskSizeBytes(paths *linuxpath.Paths, disk string) uint64 { - // We can find the number of 512-byte sectors by examining the contents of - // /sys/block/$DEVICE/size and calculate the physical bytes accordingly. - path := filepath.Join(paths.SysBlock, disk, "size") - contents, err := ioutil.ReadFile(path) - if err != nil { - return 0 - } - size, err := strconv.ParseUint(strings.TrimSpace(string(contents)), 10, 64) - if err != nil { - return 0 - } - return size * sectorSize -} - -func diskNUMANodeID(paths *linuxpath.Paths, disk string) int { - link, err := os.Readlink(filepath.Join(paths.SysBlock, disk)) - if err != nil { - return -1 - } - for partial := link; strings.HasPrefix(partial, "../devices/"); partial = filepath.Base(partial) { - if nodeContents, err := ioutil.ReadFile(filepath.Join(paths.SysBlock, partial, "numa_node")); err != nil { - if nodeInt, err := strconv.Atoi(string(nodeContents)); err != nil { - return nodeInt - } - } - } - return -1 -} - -func diskVendor(paths *linuxpath.Paths, disk string) string { - // In Linux, the vendor for a disk device is found in the - // /sys/block/$DEVICE/device/vendor file in sysfs - path := filepath.Join(paths.SysBlock, disk, "device", "vendor") - contents, err := ioutil.ReadFile(path) - if err != nil { - return util.UNKNOWN - } - return strings.TrimSpace(string(contents)) -} - -func udevInfo(paths *linuxpath.Paths, disk string) (map[string]string, error) { - // Get device major:minor numbers - devNo, err := ioutil.ReadFile(filepath.Join(paths.SysBlock, disk, "dev")) - if err != nil { - return nil, err - } - - // Look up block device in udev runtime database - udevID := "b" + strings.TrimSpace(string(devNo)) - udevBytes, err := ioutil.ReadFile(filepath.Join(paths.RunUdevData, udevID)) - if err != nil { - return nil, err - } - - udevInfo := make(map[string]string) - for _, udevLine := range strings.Split(string(udevBytes), "\n") { - if strings.HasPrefix(udevLine, "E:") { - if s := strings.SplitN(udevLine[2:], "=", 2); len(s) == 2 { - udevInfo[s[0]] = s[1] - } - } - } - return udevInfo, nil -} - -func diskModel(paths *linuxpath.Paths, disk string) string { - info, err := udevInfo(paths, disk) - if err != nil { - return util.UNKNOWN - } - - if model, ok := info["ID_MODEL"]; ok { - return model - } - return util.UNKNOWN -} - -func diskSerialNumber(paths *linuxpath.Paths, disk string) string { - info, err := udevInfo(paths, disk) - if err != nil { - return util.UNKNOWN - } - - // There are two serial number keys, ID_SERIAL and ID_SERIAL_SHORT The - // non-_SHORT version often duplicates vendor information collected - // elsewhere, so use _SHORT and fall back to ID_SERIAL if missing... - if serial, ok := info["ID_SERIAL_SHORT"]; ok { - return serial - } - if serial, ok := info["ID_SERIAL"]; ok { - return serial - } - return util.UNKNOWN -} - -func diskBusPath(paths *linuxpath.Paths, disk string) string { - info, err := udevInfo(paths, disk) - if err != nil { - return util.UNKNOWN - } - - // There are two path keys, ID_PATH and ID_PATH_TAG. - // The difference seems to be _TAG has funky characters converted to underscores. - if path, ok := info["ID_PATH"]; ok { - return path - } - return util.UNKNOWN -} - -func diskWWN(paths *linuxpath.Paths, disk string) string { - info, err := udevInfo(paths, disk) - if err != nil { - return util.UNKNOWN - } - - // Trying ID_WWN_WITH_EXTENSION and falling back to ID_WWN is the same logic lsblk uses - if wwn, ok := info["ID_WWN_WITH_EXTENSION"]; ok { - return wwn - } - if wwn, ok := info["ID_WWN"]; ok { - return wwn - } - return util.UNKNOWN -} - -// diskPartitions takes the name of a disk (note: *not* the path of the disk, -// but just the name. In other words, "sda", not "/dev/sda" and "nvme0n1" not -// "/dev/nvme0n1") and returns a slice of pointers to Partition structs -// representing the partitions in that disk -func diskPartitions(ctx *context.Context, paths *linuxpath.Paths, disk string) []*Partition { - out := make([]*Partition, 0) - path := filepath.Join(paths.SysBlock, disk) - files, err := ioutil.ReadDir(path) - if err != nil { - ctx.Warn("failed to read disk partitions: %s\n", err) - return out - } - for _, file := range files { - fname := file.Name() - if !strings.HasPrefix(fname, disk) { - continue - } - size := partitionSizeBytes(paths, disk, fname) - mp, pt, ro := partitionInfo(paths, fname) - du := diskPartUUID(ctx, fname) - p := &Partition{ - Name: fname, - SizeBytes: size, - MountPoint: mp, - Type: pt, - IsReadOnly: ro, - UUID: du, - } - out = append(out, p) - } - return out -} - -func diskPartUUID(ctx *context.Context, part string) string { - if !strings.HasPrefix(part, "/dev") { - part = "/dev/" + part - } - args := []string{ - "blkid", - "-s", - "PARTUUID", - part, - } - out, err := exec.Command(args[0], args[1:]...).Output() - if err != nil { - ctx.Warn("failed to read disk partuuid of %s : %s\n", part, err.Error()) - return "" - } - - if out == nil || len(out) == 0 { - return "" - } - - parts := strings.Split(string(out), "PARTUUID=") - if len(parts) != 2 { - ctx.Warn("failed to parse the partuuid of %s\n", part) - return "" - } - - return strings.ReplaceAll(strings.TrimSpace(parts[1]), `"`, "") -} - -func diskIsRemovable(paths *linuxpath.Paths, disk string) bool { - path := filepath.Join(paths.SysBlock, disk, "removable") - contents, err := ioutil.ReadFile(path) - if err != nil { - return false - } - removable := strings.TrimSpace(string(contents)) - if removable == "1" { - return true - } - return false -} - -func disks(ctx *context.Context, paths *linuxpath.Paths) []*Disk { - // In Linux, we could use the fdisk, lshw or blockdev commands to list disk - // information, however all of these utilities require root privileges to - // run. We can get all of this information by examining the /sys/block - // and /sys/class/block files - disks := make([]*Disk, 0) - files, err := ioutil.ReadDir(paths.SysBlock) - if err != nil { - return nil - } - for _, file := range files { - dname := file.Name() - if strings.HasPrefix(dname, "loop") { - continue - } - - driveType, storageController := diskTypes(dname) - // TODO(jaypipes): Move this into diskTypes() once abstracting - // diskIsRotational for ease of unit testing - if !diskIsRotational(ctx, paths, dname) { - driveType = DRIVE_TYPE_SSD - } - size := diskSizeBytes(paths, dname) - pbs := diskPhysicalBlockSizeBytes(paths, dname) - busPath := diskBusPath(paths, dname) - node := diskNUMANodeID(paths, dname) - vendor := diskVendor(paths, dname) - model := diskModel(paths, dname) - serialNo := diskSerialNumber(paths, dname) - wwn := diskWWN(paths, dname) - removable := diskIsRemovable(paths, dname) - - d := &Disk{ - Name: dname, - SizeBytes: size, - PhysicalBlockSizeBytes: pbs, - DriveType: driveType, - IsRemovable: removable, - StorageController: storageController, - BusPath: busPath, - NUMANodeID: node, - Vendor: vendor, - Model: model, - SerialNumber: serialNo, - WWN: wwn, - } - - parts := diskPartitions(ctx, paths, dname) - // Map this Disk object into the Partition... - for _, part := range parts { - part.Disk = d - } - d.Partitions = parts - - disks = append(disks, d) - } - - return disks -} - -// diskTypes returns the drive type, storage controller and bus type of a disk -func diskTypes(dname string) ( - DriveType, - StorageController, -) { - // The conditionals below which set the controller and drive type are - // based on information listed here: - // https://en.wikipedia.org/wiki/Device_file - driveType := DRIVE_TYPE_UNKNOWN - storageController := STORAGE_CONTROLLER_UNKNOWN - if strings.HasPrefix(dname, "fd") { - driveType = DRIVE_TYPE_FDD - } else if strings.HasPrefix(dname, "sd") { - driveType = DRIVE_TYPE_HDD - storageController = STORAGE_CONTROLLER_SCSI - } else if strings.HasPrefix(dname, "hd") { - driveType = DRIVE_TYPE_HDD - storageController = STORAGE_CONTROLLER_IDE - } else if strings.HasPrefix(dname, "vd") { - driveType = DRIVE_TYPE_HDD - storageController = STORAGE_CONTROLLER_VIRTIO - } else if strings.HasPrefix(dname, "nvme") { - driveType = DRIVE_TYPE_SSD - storageController = STORAGE_CONTROLLER_NVME - } else if strings.HasPrefix(dname, "sr") { - driveType = DRIVE_TYPE_ODD - storageController = STORAGE_CONTROLLER_SCSI - } else if strings.HasPrefix(dname, "xvd") { - driveType = DRIVE_TYPE_HDD - storageController = STORAGE_CONTROLLER_SCSI - } else if strings.HasPrefix(dname, "mmc") { - driveType = DRIVE_TYPE_SSD - storageController = STORAGE_CONTROLLER_MMC - } - - return driveType, storageController -} - -func diskIsRotational(ctx *context.Context, paths *linuxpath.Paths, devName string) bool { - path := filepath.Join(paths.SysBlock, devName, "queue", "rotational") - contents := util.SafeIntFromFile(ctx, path) - return contents == 1 -} - -// partitionSizeBytes returns the size in bytes of the partition given a disk -// name and a partition name. Note: disk name and partition name do *not* -// contain any leading "/dev" parts. In other words, they are *names*, not -// paths. -func partitionSizeBytes(paths *linuxpath.Paths, disk string, part string) uint64 { - path := filepath.Join(paths.SysBlock, disk, part, "size") - contents, err := ioutil.ReadFile(path) - if err != nil { - return 0 - } - size, err := strconv.ParseUint(strings.TrimSpace(string(contents)), 10, 64) - if err != nil { - return 0 - } - return size * sectorSize -} - -// Given a full or short partition name, returns the mount point, the type of -// the partition and whether it's readonly -func partitionInfo(paths *linuxpath.Paths, part string) (string, string, bool) { - // Allow calling PartitionInfo with either the full partition name - // "/dev/sda1" or just "sda1" - if !strings.HasPrefix(part, "/dev") { - part = "/dev/" + part - } - - // /etc/mtab entries for mounted partitions look like this: - // /dev/sda6 / ext4 rw,relatime,errors=remount-ro,data=ordered 0 0 - var r io.ReadCloser - r, err := os.Open(paths.EtcMtab) - if err != nil { - return "", "", true - } - defer util.SafeClose(r) - - scanner := bufio.NewScanner(r) - for scanner.Scan() { - line := scanner.Text() - entry := parseMtabEntry(line) - if entry == nil || entry.Partition != part { - continue - } - ro := true - for _, opt := range entry.Options { - if opt == "rw" { - ro = false - break - } - } - - return entry.Mountpoint, entry.FilesystemType, ro - } - return "", "", true -} - -type mtabEntry struct { - Partition string - Mountpoint string - FilesystemType string - Options []string -} - -func parseMtabEntry(line string) *mtabEntry { - // /etc/mtab entries for mounted partitions look like this: - // /dev/sda6 / ext4 rw,relatime,errors=remount-ro,data=ordered 0 0 - if line[0] != '/' { - return nil - } - fields := strings.Fields(line) - - if len(fields) < 4 { - return nil - } - - // We do some special parsing of the mountpoint, which may contain space, - // tab and newline characters, encoded into the mtab entry line using their - // octal-to-string representations. From the GNU mtab man pages: - // - // "Therefore these characters are encoded in the files and the getmntent - // function takes care of the decoding while reading the entries back in. - // '\040' is used to encode a space character, '\011' to encode a tab - // character, '\012' to encode a newline character, and '\\' to encode a - // backslash." - mp := fields[1] - r := strings.NewReplacer( - "\\011", "\t", "\\012", "\n", "\\040", " ", "\\\\", "\\", - ) - mp = r.Replace(mp) - - res := &mtabEntry{ - Partition: fields[0], - Mountpoint: mp, - FilesystemType: fields[2], - } - opts := strings.Split(fields[3], ",") - res.Options = opts - return res -} - -func partitionMountPoint(paths *linuxpath.Paths, part string) string { - mp, _, _ := partitionInfo(paths, part) - return mp -} - -func partitionType(paths *linuxpath.Paths, part string) string { - _, pt, _ := partitionInfo(paths, part) - return pt -} - -func partitionIsReadOnly(paths *linuxpath.Paths, part string) bool { - _, _, ro := partitionInfo(paths, part) - return ro -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/block/block_stub.go b/vendor/github.com/jaypipes/ghw/pkg/block/block_stub.go deleted file mode 100644 index 033725de4e..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/block/block_stub.go +++ /dev/null @@ -1,17 +0,0 @@ -// +build !linux,!darwin,!windows -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package block - -import ( - "runtime" - - "github.com/pkg/errors" -) - -func (i *Info) load() error { - return errors.New("blockFillInfo not implemented on " + runtime.GOOS) -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/block/block_windows.go b/vendor/github.com/jaypipes/ghw/pkg/block/block_windows.go deleted file mode 100644 index 75c6f04c7b..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/block/block_windows.go +++ /dev/null @@ -1,220 +0,0 @@ -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package block - -import ( - "strings" - - "github.com/StackExchange/wmi" - - "github.com/jaypipes/ghw/pkg/util" -) - -const wqlDiskDrive = "SELECT Caption, CreationClassName, DefaultBlockSize, Description, DeviceID, Index, InterfaceType, Manufacturer, MediaType, Model, Name, Partitions, SerialNumber, Size, TotalCylinders, TotalHeads, TotalSectors, TotalTracks, TracksPerCylinder FROM Win32_DiskDrive" - -type win32DiskDrive struct { - Caption *string - CreationClassName *string - DefaultBlockSize *uint64 - Description *string - DeviceID *string - Index *uint32 // Used to link with partition - InterfaceType *string - Manufacturer *string - MediaType *string - Model *string - Name *string - Partitions *int32 - SerialNumber *string - Size *uint64 - TotalCylinders *int64 - TotalHeads *int32 - TotalSectors *int64 - TotalTracks *int64 - TracksPerCylinder *int32 -} - -const wqlDiskPartition = "SELECT Access, BlockSize, Caption, CreationClassName, Description, DeviceID, DiskIndex, Index, Name, Size, SystemName, Type FROM Win32_DiskPartition" - -type win32DiskPartition struct { - Access *uint16 - BlockSize *uint64 - Caption *string - CreationClassName *string - Description *string - DeviceID *string - DiskIndex *uint32 // Used to link with Disk Drive - Index *uint32 - Name *string - Size *int64 - SystemName *string - Type *string -} - -const wqlLogicalDiskToPartition = "SELECT Antecedent, Dependent FROM Win32_LogicalDiskToPartition" - -type win32LogicalDiskToPartition struct { - Antecedent *string - Dependent *string -} - -const wqlLogicalDisk = "SELECT Caption, CreationClassName, Description, DeviceID, FileSystem, FreeSpace, Name, Size, SystemName FROM Win32_LogicalDisk" - -type win32LogicalDisk struct { - Caption *string - CreationClassName *string - Description *string - DeviceID *string - FileSystem *string - FreeSpace *uint64 - Name *string - Size *uint64 - SystemName *string -} - -func (i *Info) load() error { - win32DiskDriveDescriptions, err := getDiskDrives() - if err != nil { - return err - } - - win32DiskPartitionDescriptions, err := getDiskPartitions() - if err != nil { - return err - } - - win32LogicalDiskToPartitionDescriptions, err := getLogicalDisksToPartitions() - if err != nil { - return err - } - - win32LogicalDiskDescriptions, err := getLogicalDisks() - if err != nil { - return err - } - - // Converting into standard structures - disks := make([]*Disk, 0) - for _, diskdrive := range win32DiskDriveDescriptions { - disk := &Disk{ - Name: strings.TrimSpace(*diskdrive.DeviceID), - SizeBytes: *diskdrive.Size, - PhysicalBlockSizeBytes: *diskdrive.DefaultBlockSize, - DriveType: toDriveType(*diskdrive.MediaType, *diskdrive.Caption), - StorageController: toStorageController(*diskdrive.InterfaceType), - BusPath: util.UNKNOWN, // TODO: add information - NUMANodeID: -1, - Vendor: strings.TrimSpace(*diskdrive.Manufacturer), - Model: strings.TrimSpace(*diskdrive.Caption), - SerialNumber: strings.TrimSpace(*diskdrive.SerialNumber), - WWN: util.UNKNOWN, // TODO: add information - Partitions: make([]*Partition, 0), - } - for _, diskpartition := range win32DiskPartitionDescriptions { - // Finding disk partition linked to current disk drive - if diskdrive.Index == diskpartition.DiskIndex { - disk.PhysicalBlockSizeBytes = *diskpartition.BlockSize - // Finding logical partition linked to current disk partition - for _, logicaldisk := range win32LogicalDiskDescriptions { - for _, logicaldisktodiskpartition := range win32LogicalDiskToPartitionDescriptions { - var desiredAntecedent = "\\\\" + *diskpartition.SystemName + "\\root\\cimv2:" + *diskpartition.CreationClassName + ".DeviceID=\"" + *diskpartition.DeviceID + "\"" - var desiredDependent = "\\\\" + *logicaldisk.SystemName + "\\root\\cimv2:" + *logicaldisk.CreationClassName + ".DeviceID=\"" + *logicaldisk.DeviceID + "\"" - if *logicaldisktodiskpartition.Antecedent == desiredAntecedent && *logicaldisktodiskpartition.Dependent == desiredDependent { - // Appending Partition - p := &Partition{ - Name: strings.TrimSpace(*logicaldisk.Caption), - Label: strings.TrimSpace(*logicaldisk.Caption), - SizeBytes: *logicaldisk.Size, - MountPoint: *logicaldisk.DeviceID, - Type: *diskpartition.Type, - IsReadOnly: toReadOnly(*diskpartition.Access), - UUID: "", - } - disk.Partitions = append(disk.Partitions, p) - break - } - } - } - } - } - disks = append(disks, disk) - } - - i.Disks = disks - var tpb uint64 - for _, d := range i.Disks { - tpb += d.SizeBytes - } - i.TotalPhysicalBytes = tpb - return nil -} - -func getDiskDrives() ([]win32DiskDrive, error) { - // Getting disks drives data from WMI - var win3232DiskDriveDescriptions []win32DiskDrive - if err := wmi.Query(wqlDiskDrive, &win3232DiskDriveDescriptions); err != nil { - return nil, err - } - return win3232DiskDriveDescriptions, nil -} - -func getDiskPartitions() ([]win32DiskPartition, error) { - // Getting disk partitions from WMI - var win32DiskPartitionDescriptions []win32DiskPartition - if err := wmi.Query(wqlDiskPartition, &win32DiskPartitionDescriptions); err != nil { - return nil, err - } - return win32DiskPartitionDescriptions, nil -} - -func getLogicalDisksToPartitions() ([]win32LogicalDiskToPartition, error) { - // Getting links between logical disks and partitions from WMI - var win32LogicalDiskToPartitionDescriptions []win32LogicalDiskToPartition - if err := wmi.Query(wqlLogicalDiskToPartition, &win32LogicalDiskToPartitionDescriptions); err != nil { - return nil, err - } - return win32LogicalDiskToPartitionDescriptions, nil -} - -func getLogicalDisks() ([]win32LogicalDisk, error) { - // Getting logical disks from WMI - var win32LogicalDiskDescriptions []win32LogicalDisk - if err := wmi.Query(wqlLogicalDisk, &win32LogicalDiskDescriptions); err != nil { - return nil, err - } - return win32LogicalDiskDescriptions, nil -} - -func toDriveType(mediaType string, caption string) DriveType { - mediaType = strings.ToLower(mediaType) - caption = strings.ToLower(caption) - if strings.Contains(mediaType, "fixed") || strings.Contains(mediaType, "ssd") || strings.Contains(caption, "ssd") { - return DRIVE_TYPE_SSD - } else if strings.ContainsAny(mediaType, "hdd") { - return DRIVE_TYPE_HDD - } - return DRIVE_TYPE_UNKNOWN -} - -// TODO: improve -func toStorageController(interfaceType string) StorageController { - var storageController StorageController - switch interfaceType { - case "SCSI": - storageController = STORAGE_CONTROLLER_SCSI - case "IDE": - storageController = STORAGE_CONTROLLER_IDE - default: - storageController = STORAGE_CONTROLLER_UNKNOWN - } - return storageController -} - -// TODO: improve -func toReadOnly(access uint16) bool { - // See Access property from: https://docs.microsoft.com/en-us/windows/win32/cimwin32prov/win32-diskpartition - return access == 0x1 -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/chassis/chassis.go b/vendor/github.com/jaypipes/ghw/pkg/chassis/chassis.go deleted file mode 100644 index e11f0447a9..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/chassis/chassis.go +++ /dev/null @@ -1,121 +0,0 @@ -// -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package chassis - -import ( - "fmt" - - "github.com/jaypipes/ghw/pkg/context" - "github.com/jaypipes/ghw/pkg/marshal" - "github.com/jaypipes/ghw/pkg/option" - "github.com/jaypipes/ghw/pkg/util" -) - -var ( - chassisTypeDescriptions = map[string]string{ - "1": "Other", - "2": "Unknown", - "3": "Desktop", - "4": "Low profile desktop", - "5": "Pizza box", - "6": "Mini tower", - "7": "Tower", - "8": "Portable", - "9": "Laptop", - "10": "Notebook", - "11": "Hand held", - "12": "Docking station", - "13": "All in one", - "14": "Sub notebook", - "15": "Space-saving", - "16": "Lunch box", - "17": "Main server chassis", - "18": "Expansion chassis", - "19": "SubChassis", - "20": "Bus Expansion chassis", - "21": "Peripheral chassis", - "22": "RAID chassis", - "23": "Rack mount chassis", - "24": "Sealed-case PC", - "25": "Multi-system chassis", - "26": "Compact PCI", - "27": "Advanced TCA", - "28": "Blade", - "29": "Blade enclosure", - "30": "Tablet", - "31": "Convertible", - "32": "Detachable", - "33": "IoT gateway", - "34": "Embedded PC", - "35": "Mini PC", - "36": "Stick PC", - } -) - -// Info defines chassis release information -type Info struct { - ctx *context.Context - AssetTag string `json:"asset_tag"` - SerialNumber string `json:"serial_number"` - Type string `json:"type"` - TypeDescription string `json:"type_description"` - Vendor string `json:"vendor"` - Version string `json:"version"` -} - -func (i *Info) String() string { - vendorStr := "" - if i.Vendor != "" { - vendorStr = " vendor=" + i.Vendor - } - serialStr := "" - if i.SerialNumber != "" && i.SerialNumber != util.UNKNOWN { - serialStr = " serial=" + i.SerialNumber - } - versionStr := "" - if i.Version != "" { - versionStr = " version=" + i.Version - } - - res := fmt.Sprintf( - "chassis type=%s%s%s%s", - i.TypeDescription, - vendorStr, - serialStr, - versionStr, - ) - return res -} - -// New returns a pointer to a Info struct containing information -// about the host's chassis -func New(opts ...*option.Option) (*Info, error) { - ctx := context.New(opts...) - info := &Info{ctx: ctx} - if err := ctx.Do(info.load); err != nil { - return nil, err - } - return info, nil -} - -// simple private struct used to encapsulate chassis information in a top-level -// "chassis" YAML/JSON map/object key -type chassisPrinter struct { - Info *Info `json:"chassis"` -} - -// YAMLString returns a string with the chassis information formatted as YAML -// under a top-level "dmi:" key -func (info *Info) YAMLString() string { - return marshal.SafeYAML(info.ctx, chassisPrinter{info}) -} - -// JSONString returns a string with the chassis information formatted as JSON -// under a top-level "chassis:" key -func (info *Info) JSONString(indent bool) string { - return marshal.SafeJSON(info.ctx, chassisPrinter{info}, indent) -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/chassis/chassis_linux.go b/vendor/github.com/jaypipes/ghw/pkg/chassis/chassis_linux.go deleted file mode 100644 index 00f64de6e0..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/chassis/chassis_linux.go +++ /dev/null @@ -1,26 +0,0 @@ -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package chassis - -import ( - "github.com/jaypipes/ghw/pkg/linuxdmi" - "github.com/jaypipes/ghw/pkg/util" -) - -func (i *Info) load() error { - i.AssetTag = linuxdmi.Item(i.ctx, "chassis_asset_tag") - i.SerialNumber = linuxdmi.Item(i.ctx, "chassis_serial") - i.Type = linuxdmi.Item(i.ctx, "chassis_type") - typeDesc, found := chassisTypeDescriptions[i.Type] - if !found { - typeDesc = util.UNKNOWN - } - i.TypeDescription = typeDesc - i.Vendor = linuxdmi.Item(i.ctx, "chassis_vendor") - i.Version = linuxdmi.Item(i.ctx, "chassis_version") - - return nil -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/chassis/chassis_stub.go b/vendor/github.com/jaypipes/ghw/pkg/chassis/chassis_stub.go deleted file mode 100644 index 2e45e15a52..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/chassis/chassis_stub.go +++ /dev/null @@ -1,17 +0,0 @@ -// +build !linux,!windows -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package chassis - -import ( - "runtime" - - "github.com/pkg/errors" -) - -func (i *Info) load() error { - return errors.New("chassisFillInfo not implemented on " + runtime.GOOS) -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/chassis/chassis_windows.go b/vendor/github.com/jaypipes/ghw/pkg/chassis/chassis_windows.go deleted file mode 100644 index 088cbed3cb..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/chassis/chassis_windows.go +++ /dev/null @@ -1,43 +0,0 @@ -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package chassis - -import ( - "github.com/StackExchange/wmi" - - "github.com/jaypipes/ghw/pkg/util" -) - -const wqlChassis = "SELECT Caption, Description, Name, Manufacturer, Model, SerialNumber, Tag, TypeDescriptions, Version FROM CIM_Chassis" - -type win32Chassis struct { - Caption *string - Description *string - Name *string - Manufacturer *string - Model *string - SerialNumber *string - Tag *string - TypeDescriptions []string - Version *string -} - -func (i *Info) load() error { - // Getting data from WMI - var win32ChassisDescriptions []win32Chassis - if err := wmi.Query(wqlChassis, &win32ChassisDescriptions); err != nil { - return err - } - if len(win32ChassisDescriptions) > 0 { - i.AssetTag = *win32ChassisDescriptions[0].Tag - i.SerialNumber = *win32ChassisDescriptions[0].SerialNumber - i.Type = util.UNKNOWN // TODO: - i.TypeDescription = *win32ChassisDescriptions[0].Model - i.Vendor = *win32ChassisDescriptions[0].Manufacturer - i.Version = *win32ChassisDescriptions[0].Version - } - return nil -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/context/context.go b/vendor/github.com/jaypipes/ghw/pkg/context/context.go deleted file mode 100644 index 315c2d8bb0..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/context/context.go +++ /dev/null @@ -1,128 +0,0 @@ -// -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package context - -import ( - "github.com/jaypipes/ghw/pkg/option" - "github.com/jaypipes/ghw/pkg/snapshot" -) - -// Concrete merged set of configuration switches that act as an execution -// context when calling internal discovery methods -type Context struct { - Chroot string - EnableTools bool - SnapshotPath string - SnapshotRoot string - SnapshotExclusive bool - snapshotUnpackedPath string - alert option.Alerter -} - -// New returns a Context struct pointer that has had various options set on it -func New(opts ...*option.Option) *Context { - merged := option.Merge(opts...) - ctx := &Context{ - alert: option.EnvOrDefaultAlerter(), - Chroot: *merged.Chroot, - } - - if merged.Snapshot != nil { - ctx.SnapshotPath = merged.Snapshot.Path - // root is optional, so a extra check is warranted - if merged.Snapshot.Root != nil { - ctx.SnapshotRoot = *merged.Snapshot.Root - } - ctx.SnapshotExclusive = merged.Snapshot.Exclusive - } - - if merged.Alerter != nil { - ctx.alert = merged.Alerter - } - - if merged.EnableTools != nil { - ctx.EnableTools = *merged.EnableTools - } - - return ctx -} - -// FromEnv returns an Option that has been populated from the environs or -// default options values -func FromEnv() *Context { - chrootVal := option.EnvOrDefaultChroot() - enableTools := option.EnvOrDefaultTools() - snapPathVal := option.EnvOrDefaultSnapshotPath() - snapRootVal := option.EnvOrDefaultSnapshotRoot() - snapExclusiveVal := option.EnvOrDefaultSnapshotExclusive() - return &Context{ - Chroot: chrootVal, - EnableTools: enableTools, - SnapshotPath: snapPathVal, - SnapshotRoot: snapRootVal, - SnapshotExclusive: snapExclusiveVal, - } -} - -// Do wraps a Setup/Teardown pair around the given function -func (ctx *Context) Do(fn func() error) error { - err := ctx.Setup() - if err != nil { - return err - } - defer ctx.Teardown() - return fn() -} - -// Setup prepares the extra optional data a Context may use. -// `Context`s are ready to use once returned by `New`. Optional features, -// like snapshot unpacking, may require extra steps. Run `Setup` to perform them. -// You should call `Setup` just once. It is safe to call `Setup` if you don't make -// use of optional extra features - `Setup` will do nothing. -func (ctx *Context) Setup() error { - if ctx.SnapshotPath == "" { - // nothing to do! - return nil - } - - var err error - root := ctx.SnapshotRoot - if root == "" { - root, err = snapshot.Unpack(ctx.SnapshotPath) - if err == nil { - ctx.snapshotUnpackedPath = root - } - } else { - var flags uint - if ctx.SnapshotExclusive { - flags |= snapshot.OwnTargetDirectory - } - _, err = snapshot.UnpackInto(ctx.SnapshotPath, root, flags) - } - if err != nil { - return err - } - - ctx.Chroot = root - return nil -} - -// Teardown releases any resource acquired by Setup. -// You should always call `Teardown` if you called `Setup` to free any resources -// acquired by `Setup`. Check `Do` for more automated management. -func (ctx *Context) Teardown() error { - if ctx.snapshotUnpackedPath == "" { - // if the client code provided the unpack directory, - // then it is also in charge of the cleanup. - return nil - } - return snapshot.Cleanup(ctx.snapshotUnpackedPath) -} - -func (ctx *Context) Warn(msg string, args ...interface{}) { - ctx.alert.Printf("WARNING: "+msg, args...) -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/cpu/cpu.go b/vendor/github.com/jaypipes/ghw/pkg/cpu/cpu.go deleted file mode 100644 index 2fa0cd2d06..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/cpu/cpu.go +++ /dev/null @@ -1,169 +0,0 @@ -// -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package cpu - -import ( - "fmt" - - "github.com/jaypipes/ghw/pkg/context" - "github.com/jaypipes/ghw/pkg/marshal" - "github.com/jaypipes/ghw/pkg/option" -) - -// ProcessorCore describes a physical host processor core. A processor core is -// a separate processing unit within some types of central processing units -// (CPU). -type ProcessorCore struct { - // ID is the `uint32` identifier that the host gave this core. Note that - // this does *not* necessarily equate to a zero-based index of the core - // within a physical package. For example, the core IDs for an Intel Core - // i7 are 0, 1, 2, 8, 9, and 10 - ID int `json:"id"` - // Index is the zero-based index of the core on the physical processor - // package - Index int `json:"index"` - // NumThreads is the number of hardware threads associated with the core - NumThreads uint32 `json:"total_threads"` - // LogicalProcessors is a slice of ints representing the logical processor - // IDs assigned to any processing unit for the core - LogicalProcessors []int `json:"logical_processors"` -} - -// String returns a short string indicating important information about the -// processor core -func (c *ProcessorCore) String() string { - return fmt.Sprintf( - "processor core #%d (%d threads), logical processors %v", - c.Index, - c.NumThreads, - c.LogicalProcessors, - ) -} - -// Processor describes a physical host central processing unit (CPU). -type Processor struct { - // ID is the physical processor `uint32` ID according to the system - ID int `json:"id"` - // NumCores is the number of physical cores in the processor package - NumCores uint32 `json:"total_cores"` - // NumThreads is the number of hardware threads in the processor package - NumThreads uint32 `json:"total_threads"` - // Vendor is a string containing the vendor name - Vendor string `json:"vendor"` - // Model` is a string containing the vendor's model name - Model string `json:"model"` - // Capabilities is a slice of strings indicating the features the processor - // has enabled - Capabilities []string `json:"capabilities"` - // Cores is a slice of ProcessorCore` struct pointers that are packed onto - // this physical processor - Cores []*ProcessorCore `json:"cores"` -} - -// HasCapability returns true if the Processor has the supplied cpuid -// capability, false otherwise. Example of cpuid capabilities would be 'vmx' or -// 'sse4_2'. To see a list of potential cpuid capabilitiies, see the section on -// CPUID feature bits in the following article: -// -// https://en.wikipedia.org/wiki/CPUID -func (p *Processor) HasCapability(find string) bool { - for _, c := range p.Capabilities { - if c == find { - return true - } - } - return false -} - -// String returns a short string describing the Processor -func (p *Processor) String() string { - ncs := "cores" - if p.NumCores == 1 { - ncs = "core" - } - nts := "threads" - if p.NumThreads == 1 { - nts = "thread" - } - return fmt.Sprintf( - "physical package #%d (%d %s, %d hardware %s)", - p.ID, - p.NumCores, - ncs, - p.NumThreads, - nts, - ) -} - -// Info describes all central processing unit (CPU) functionality on a host. -// Returned by the `ghw.CPU()` function. -type Info struct { - ctx *context.Context - // TotalCores is the total number of physical cores the host system - // contains - TotalCores uint32 `json:"total_cores"` - // TotalThreads is the total number of hardware threads the host system - // contains - TotalThreads uint32 `json:"total_threads"` - // Processors is a slice of Processor struct pointers, one for each - // physical processor package contained in the host - Processors []*Processor `json:"processors"` -} - -// New returns a pointer to an Info struct that contains information about the -// CPUs on the host system -func New(opts ...*option.Option) (*Info, error) { - ctx := context.New(opts...) - info := &Info{ctx: ctx} - if err := ctx.Do(info.load); err != nil { - return nil, err - } - return info, nil -} - -// String returns a short string indicating a summary of CPU information -func (i *Info) String() string { - nps := "packages" - if len(i.Processors) == 1 { - nps = "package" - } - ncs := "cores" - if i.TotalCores == 1 { - ncs = "core" - } - nts := "threads" - if i.TotalThreads == 1 { - nts = "thread" - } - return fmt.Sprintf( - "cpu (%d physical %s, %d %s, %d hardware %s)", - len(i.Processors), - nps, - i.TotalCores, - ncs, - i.TotalThreads, - nts, - ) -} - -// simple private struct used to encapsulate cpu information in a top-level -// "cpu" YAML/JSON map/object key -type cpuPrinter struct { - Info *Info `json:"cpu"` -} - -// YAMLString returns a string with the cpu information formatted as YAML -// under a top-level "cpu:" key -func (i *Info) YAMLString() string { - return marshal.SafeYAML(i.ctx, cpuPrinter{i}) -} - -// JSONString returns a string with the cpu information formatted as JSON -// under a top-level "cpu:" key -func (i *Info) JSONString(indent bool) string { - return marshal.SafeJSON(i.ctx, cpuPrinter{i}, indent) -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/cpu/cpu_linux.go b/vendor/github.com/jaypipes/ghw/pkg/cpu/cpu_linux.go deleted file mode 100644 index 44e4ced745..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/cpu/cpu_linux.go +++ /dev/null @@ -1,220 +0,0 @@ -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package cpu - -import ( - "bufio" - "fmt" - "io/ioutil" - "os" - "path/filepath" - "strconv" - "strings" - - "github.com/jaypipes/ghw/pkg/context" - "github.com/jaypipes/ghw/pkg/linuxpath" - "github.com/jaypipes/ghw/pkg/util" -) - -func (i *Info) load() error { - i.Processors = processorsGet(i.ctx) - var totCores uint32 - var totThreads uint32 - for _, p := range i.Processors { - totCores += p.NumCores - totThreads += p.NumThreads - } - i.TotalCores = totCores - i.TotalThreads = totThreads - return nil -} - -func processorsGet(ctx *context.Context) []*Processor { - procs := make([]*Processor, 0) - paths := linuxpath.New(ctx) - - r, err := os.Open(paths.ProcCpuinfo) - if err != nil { - return nil - } - defer util.SafeClose(r) - - // An array of maps of attributes describing the logical processor - procAttrs := make([]map[string]string, 0) - curProcAttrs := make(map[string]string) - - scanner := bufio.NewScanner(r) - for scanner.Scan() { - line := strings.TrimSpace(scanner.Text()) - if line == "" { - // Output of /proc/cpuinfo has a blank newline to separate logical - // processors, so here we collect up all the attributes we've - // collected for this logical processor block - procAttrs = append(procAttrs, curProcAttrs) - // Reset the current set of processor attributes... - curProcAttrs = make(map[string]string) - continue - } - parts := strings.Split(line, ":") - key := strings.TrimSpace(parts[0]) - value := strings.TrimSpace(parts[1]) - curProcAttrs[key] = value - } - - // Build a set of physical processor IDs which represent the physical - // package of the CPU - setPhysicalIDs := make(map[int]bool) - for _, attrs := range procAttrs { - pid, err := strconv.Atoi(attrs["physical id"]) - if err != nil { - continue - } - setPhysicalIDs[pid] = true - } - - for pid := range setPhysicalIDs { - p := &Processor{ - ID: pid, - } - // The indexes into the array of attribute maps for each logical - // processor within the physical processor - lps := make([]int, 0) - for x := range procAttrs { - lppid, err := strconv.Atoi(procAttrs[x]["physical id"]) - if err != nil { - continue - } - if pid == lppid { - lps = append(lps, x) - } - } - first := procAttrs[lps[0]] - p.Model = first["model name"] - p.Vendor = first["vendor_id"] - numCores, err := strconv.Atoi(first["cpu cores"]) - if err != nil { - continue - } - p.NumCores = uint32(numCores) - numThreads, err := strconv.Atoi(first["siblings"]) - if err != nil { - continue - } - p.NumThreads = uint32(numThreads) - - // The flags field is a space-separated list of CPU capabilities - p.Capabilities = strings.Split(first["flags"], " ") - - cores := make([]*ProcessorCore, 0) - for _, lpidx := range lps { - lpid, err := strconv.Atoi(procAttrs[lpidx]["processor"]) - if err != nil { - continue - } - coreID, err := strconv.Atoi(procAttrs[lpidx]["core id"]) - if err != nil { - continue - } - var core *ProcessorCore - for _, c := range cores { - if c.ID == coreID { - c.LogicalProcessors = append( - c.LogicalProcessors, - lpid, - ) - c.NumThreads = uint32(len(c.LogicalProcessors)) - core = c - } - } - if core == nil { - coreLps := make([]int, 1) - coreLps[0] = lpid - core = &ProcessorCore{ - ID: coreID, - Index: len(cores), - NumThreads: 1, - LogicalProcessors: coreLps, - } - cores = append(cores, core) - } - } - p.Cores = cores - procs = append(procs, p) - } - return procs -} - -func CoresForNode(ctx *context.Context, nodeID int) ([]*ProcessorCore, error) { - // The /sys/devices/system/node/nodeX directory contains a subdirectory - // called 'cpuX' for each logical processor assigned to the node. Each of - // those subdirectories contains a topology subdirectory which has a - // core_id file that indicates the 0-based identifier of the physical core - // the logical processor (hardware thread) is on. - paths := linuxpath.New(ctx) - path := filepath.Join( - paths.SysDevicesSystemNode, - fmt.Sprintf("node%d", nodeID), - ) - cores := make([]*ProcessorCore, 0) - - findCoreByID := func(coreID int) *ProcessorCore { - for _, c := range cores { - if c.ID == coreID { - return c - } - } - - c := &ProcessorCore{ - ID: coreID, - Index: len(cores), - LogicalProcessors: make([]int, 0), - } - cores = append(cores, c) - return c - } - - files, err := ioutil.ReadDir(path) - if err != nil { - return nil, err - } - for _, file := range files { - filename := file.Name() - if !strings.HasPrefix(filename, "cpu") { - continue - } - if filename == "cpumap" || filename == "cpulist" { - // There are two files in the node directory that start with 'cpu' - // but are not subdirectories ('cpulist' and 'cpumap'). Ignore - // these files. - continue - } - // Grab the logical processor ID by cutting the integer from the - // /sys/devices/system/node/nodeX/cpuX filename - cpuPath := filepath.Join(path, filename) - procID, err := strconv.Atoi(filename[3:]) - if err != nil { - _, _ = fmt.Fprintf( - os.Stderr, - "failed to determine procID from %s. Expected integer after 3rd char.", - filename, - ) - continue - } - coreIDPath := filepath.Join(cpuPath, "topology", "core_id") - coreID := util.SafeIntFromFile(ctx, coreIDPath) - core := findCoreByID(coreID) - core.LogicalProcessors = append( - core.LogicalProcessors, - procID, - ) - } - - for _, c := range cores { - c.NumThreads = uint32(len(c.LogicalProcessors)) - } - - return cores, nil -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/cpu/cpu_stub.go b/vendor/github.com/jaypipes/ghw/pkg/cpu/cpu_stub.go deleted file mode 100644 index 9ff41cd161..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/cpu/cpu_stub.go +++ /dev/null @@ -1,17 +0,0 @@ -// +build !linux,!windows -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package cpu - -import ( - "runtime" - - "github.com/pkg/errors" -) - -func (i *Info) load() error { - return errors.New("cpu.Info.load not implemented on " + runtime.GOOS) -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/cpu/cpu_windows.go b/vendor/github.com/jaypipes/ghw/pkg/cpu/cpu_windows.go deleted file mode 100644 index 07a7ddddbe..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/cpu/cpu_windows.go +++ /dev/null @@ -1,55 +0,0 @@ -// +build !linux -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package cpu - -import ( - "github.com/StackExchange/wmi" -) - -const wmqlProcessor = "SELECT Manufacturer, Name, NumberOfLogicalProcessors, NumberOfCores FROM Win32_Processor" - -type win32Processor struct { - Manufacturer *string - Name *string - NumberOfLogicalProcessors uint32 - NumberOfCores uint32 -} - -func (i *Info) load() error { - // Getting info from WMI - var win32descriptions []win32Processor - if err := wmi.Query(wmqlProcessor, &win32descriptions); err != nil { - return err - } - // Converting into standard structures - i.Processors = processorsGet(win32descriptions) - var totCores uint32 - var totThreads uint32 - for _, p := range i.Processors { - totCores += p.NumCores - totThreads += p.NumThreads - } - i.TotalCores = totCores - i.TotalThreads = totThreads - return nil -} - -func processorsGet(win32descriptions []win32Processor) []*Processor { - var procs []*Processor - // Converting into standard structures - for index, description := range win32descriptions { - p := &Processor{ - ID: index, - Model: *description.Name, - Vendor: *description.Manufacturer, - NumCores: description.NumberOfCores, - NumThreads: description.NumberOfLogicalProcessors, - } - procs = append(procs, p) - } - return procs -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/gpu/gpu.go b/vendor/github.com/jaypipes/ghw/pkg/gpu/gpu.go deleted file mode 100644 index 65864c7e14..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/gpu/gpu.go +++ /dev/null @@ -1,95 +0,0 @@ -// -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package gpu - -import ( - "fmt" - - "github.com/jaypipes/ghw/pkg/context" - "github.com/jaypipes/ghw/pkg/marshal" - "github.com/jaypipes/ghw/pkg/option" - "github.com/jaypipes/ghw/pkg/pci" - "github.com/jaypipes/ghw/pkg/topology" -) - -type GraphicsCard struct { - // the PCI address where the graphics card can be found - Address string `json:"address"` - // The "index" of the card on the bus (generally not useful information, - // but might as well include it) - Index int `json:"index"` - // pointer to a PCIDevice struct that describes the vendor and product - // model, etc - // TODO(jaypipes): Rename this field to PCI, instead of DeviceInfo - DeviceInfo *pci.Device `json:"pci"` - // Topology node that the graphics card is affined to. Will be nil if the - // architecture is not NUMA. - Node *topology.Node `json:"node,omitempty"` -} - -func (card *GraphicsCard) String() string { - deviceStr := card.Address - if card.DeviceInfo != nil { - deviceStr = card.DeviceInfo.String() - } - nodeStr := "" - if card.Node != nil { - nodeStr = fmt.Sprintf(" [affined to NUMA node %d]", card.Node.ID) - } - return fmt.Sprintf( - "card #%d %s@%s", - card.Index, - nodeStr, - deviceStr, - ) -} - -type Info struct { - ctx *context.Context - GraphicsCards []*GraphicsCard `json:"cards"` -} - -// New returns a pointer to an Info struct that contains information about the -// graphics cards on the host system -func New(opts ...*option.Option) (*Info, error) { - ctx := context.New(opts...) - info := &Info{ctx: ctx} - if err := ctx.Do(info.load); err != nil { - return nil, err - } - return info, nil -} - -func (i *Info) String() string { - numCardsStr := "cards" - if len(i.GraphicsCards) == 1 { - numCardsStr = "card" - } - return fmt.Sprintf( - "gpu (%d graphics %s)", - len(i.GraphicsCards), - numCardsStr, - ) -} - -// simple private struct used to encapsulate gpu information in a top-level -// "gpu" YAML/JSON map/object key -type gpuPrinter struct { - Info *Info `json:"gpu"` -} - -// YAMLString returns a string with the gpu information formatted as YAML -// under a top-level "gpu:" key -func (i *Info) YAMLString() string { - return marshal.SafeYAML(i.ctx, gpuPrinter{i}) -} - -// JSONString returns a string with the gpu information formatted as JSON -// under a top-level "gpu:" key -func (i *Info) JSONString(indent bool) string { - return marshal.SafeJSON(i.ctx, gpuPrinter{i}, indent) -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/gpu/gpu_linux.go b/vendor/github.com/jaypipes/ghw/pkg/gpu/gpu_linux.go deleted file mode 100644 index d5959916b5..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/gpu/gpu_linux.go +++ /dev/null @@ -1,152 +0,0 @@ -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package gpu - -import ( - "io/ioutil" - "os" - "path/filepath" - "strconv" - "strings" - - "github.com/jaypipes/ghw/pkg/context" - "github.com/jaypipes/ghw/pkg/linuxpath" - "github.com/jaypipes/ghw/pkg/pci" - "github.com/jaypipes/ghw/pkg/topology" - "github.com/jaypipes/ghw/pkg/util" -) - -const ( - _WARN_NO_SYS_CLASS_DRM = ` -/sys/class/drm does not exist on this system (likely the host system is a -virtual machine or container with no graphics). Therefore, -GPUInfo.GraphicsCards will be an empty array. -` -) - -func (i *Info) load() error { - // In Linux, each graphics card is listed under the /sys/class/drm - // directory as a symbolic link named "cardN", where N is a zero-based - // index of the card in the system. "DRM" stands for Direct Rendering - // Manager and is the Linux subsystem that is responsible for graphics I/O - // - // Each card may have multiple symbolic - // links in this directory representing the interfaces from the graphics - // card over a particular wire protocol (HDMI, DisplayPort, etc). These - // symbolic links are named cardN--. For - // instance, on one of my local workstations with an NVIDIA GTX 1050ti - // graphics card with one HDMI, one DisplayPort, and one DVI interface to - // the card, I see the following in /sys/class/drm: - // - // $ ll /sys/class/drm/ - // total 0 - // drwxr-xr-x 2 root root 0 Jul 16 11:50 ./ - // drwxr-xr-x 75 root root 0 Jul 16 11:50 ../ - // lrwxrwxrwx 1 root root 0 Jul 16 11:50 card0 -> ../../devices/pci0000:00/0000:00:03.0/0000:03:00.0/drm/card0/ - // lrwxrwxrwx 1 root root 0 Jul 16 11:50 card0-DP-1 -> ../../devices/pci0000:00/0000:00:03.0/0000:03:00.0/drm/card0/card0-DP-1/ - // lrwxrwxrwx 1 root root 0 Jul 16 11:50 card0-DVI-D-1 -> ../../devices/pci0000:00/0000:00:03.0/0000:03:00.0/drm/card0/card0-DVI-D-1/ - // lrwxrwxrwx 1 root root 0 Jul 16 11:50 card0-HDMI-A-1 -> ../../devices/pci0000:00/0000:00:03.0/0000:03:00.0/drm/card0/card0-HDMI-A-1/ - // - // In this routine, we are only interested in the first link (card0), which - // we follow to gather information about the actual device from the PCI - // subsystem (we query the modalias file of the PCI device's sysfs - // directory using the `ghw.PCIInfo.GetDevice()` function. - paths := linuxpath.New(i.ctx) - links, err := ioutil.ReadDir(paths.SysClassDRM) - if err != nil { - i.ctx.Warn(_WARN_NO_SYS_CLASS_DRM) - return nil - } - cards := make([]*GraphicsCard, 0) - for _, link := range links { - lname := link.Name() - if !strings.HasPrefix(lname, "card") { - continue - } - if strings.ContainsRune(lname, '-') { - continue - } - // Grab the card's zero-based integer index - lnameBytes := []byte(lname) - cardIdx, err := strconv.Atoi(string(lnameBytes[4:])) - if err != nil { - cardIdx = -1 - } - - // Calculate the card's PCI address by looking at the symbolic link's - // target - lpath := filepath.Join(paths.SysClassDRM, lname) - dest, err := os.Readlink(lpath) - if err != nil { - continue - } - pathParts := strings.Split(dest, "/") - numParts := len(pathParts) - pciAddress := pathParts[numParts-3] - card := &GraphicsCard{ - Address: pciAddress, - Index: cardIdx, - } - cards = append(cards, card) - } - gpuFillNUMANodes(i.ctx, cards) - gpuFillPCIDevice(i.ctx, cards) - i.GraphicsCards = cards - return nil -} - -// Loops through each GraphicsCard struct and attempts to fill the DeviceInfo -// attribute with PCI device information -func gpuFillPCIDevice(ctx *context.Context, cards []*GraphicsCard) { - pci, err := pci.NewWithContext(ctx) - if err != nil { - return - } - for _, card := range cards { - if card.DeviceInfo == nil { - card.DeviceInfo = pci.GetDevice(card.Address) - } - } -} - -// Loops through each GraphicsCard struct and find which NUMA node the card is -// affined to, setting the GraphicsCard.Node field accordingly. If the host -// system is not a NUMA system, the Node field will be set to nil. -func gpuFillNUMANodes(ctx *context.Context, cards []*GraphicsCard) { - paths := linuxpath.New(ctx) - topo, err := topology.NewWithContext(ctx) - if err != nil { - // Problem getting topology information so just set the graphics card's - // node to nil - for _, card := range cards { - if topo.Architecture != topology.ARCHITECTURE_NUMA { - card.Node = nil - } - } - return - } - for _, card := range cards { - // Each graphics card on a NUMA system will have a pseudo-file - // called /sys/class/drm/card$CARD_INDEX/device/numa_node which - // contains the NUMA node that the card is affined to - cardIndexStr := strconv.Itoa(card.Index) - fpath := filepath.Join( - paths.SysClassDRM, - "card"+cardIndexStr, - "device", - "numa_node", - ) - nodeIdx := util.SafeIntFromFile(ctx, fpath) - if nodeIdx == -1 { - continue - } - for _, node := range topo.Nodes { - if nodeIdx == int(node.ID) { - card.Node = node - } - } - } -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/gpu/gpu_stub.go b/vendor/github.com/jaypipes/ghw/pkg/gpu/gpu_stub.go deleted file mode 100644 index 9604637d86..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/gpu/gpu_stub.go +++ /dev/null @@ -1,17 +0,0 @@ -// +build !linux,!windows -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package gpu - -import ( - "runtime" - - "github.com/pkg/errors" -) - -func (i *Info) load() error { - return errors.New("gpuFillInfo not implemented on " + runtime.GOOS) -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/gpu/gpu_windows.go b/vendor/github.com/jaypipes/ghw/pkg/gpu/gpu_windows.go deleted file mode 100644 index 5fb5428149..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/gpu/gpu_windows.go +++ /dev/null @@ -1,131 +0,0 @@ -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package gpu - -import ( - "strings" - - "github.com/StackExchange/wmi" - "github.com/jaypipes/pcidb" - - "github.com/jaypipes/ghw/pkg/pci" - "github.com/jaypipes/ghw/pkg/util" -) - -const wqlVideoController = "SELECT Caption, CreationClassName, Description, DeviceID, Name, PNPDeviceID, SystemCreationClassName, SystemName, VideoArchitecture, VideoMemoryType, VideoModeDescription, VideoProcessor FROM Win32_VideoController" - -type win32VideoController struct { - Caption string - CreationClassName string - Description string - DeviceID string - Name string - PNPDeviceID string - SystemCreationClassName string - SystemName string - VideoArchitecture uint16 - VideoMemoryType uint16 - VideoModeDescription string - VideoProcessor string -} - -const wqlPnPEntity = "SELECT Caption, CreationClassName, Description, DeviceID, Manufacturer, Name, PNPClass, PNPDeviceID FROM Win32_PnPEntity" - -type win32PnPEntity struct { - Caption string - CreationClassName string - Description string - DeviceID string - Manufacturer string - Name string - PNPClass string - PNPDeviceID string -} - -func (i *Info) load() error { - // Getting data from WMI - var win32VideoControllerDescriptions []win32VideoController - if err := wmi.Query(wqlVideoController, &win32VideoControllerDescriptions); err != nil { - return err - } - - // Building dynamic WHERE clause with addresses to create a single query collecting all desired data - queryAddresses := []string{} - for _, description := range win32VideoControllerDescriptions { - var queryAddres = strings.Replace(description.PNPDeviceID, "\\", `\\`, -1) - queryAddresses = append(queryAddresses, "PNPDeviceID='"+queryAddres+"'") - } - whereClause := strings.Join(queryAddresses[:], " OR ") - - // Getting data from WMI - var win32PnPDescriptions []win32PnPEntity - var wqlPnPDevice = wqlPnPEntity + " WHERE " + whereClause - if err := wmi.Query(wqlPnPDevice, &win32PnPDescriptions); err != nil { - return err - } - - // Converting into standard structures - cards := make([]*GraphicsCard, 0) - for _, description := range win32VideoControllerDescriptions { - card := &GraphicsCard{ - Address: description.DeviceID, // https://stackoverflow.com/questions/32073667/how-do-i-discover-the-pcie-bus-topology-and-slot-numbers-on-the-board - Index: 0, - DeviceInfo: GetDevice(description.PNPDeviceID, win32PnPDescriptions), - } - cards = append(cards, card) - } - i.GraphicsCards = cards - return nil -} - -func GetDevice(id string, entities []win32PnPEntity) *pci.Device { - // Backslashing PnP address ID as requested by JSON and VMI query: https://docs.microsoft.com/en-us/windows/win32/wmisdk/where-clause - var queryAddress = strings.Replace(id, "\\", `\\`, -1) - // Preparing default structure - var device = &pci.Device{ - Address: queryAddress, - Vendor: &pcidb.Vendor{ - ID: util.UNKNOWN, - Name: util.UNKNOWN, - Products: []*pcidb.Product{}, - }, - Subsystem: &pcidb.Product{ - ID: util.UNKNOWN, - Name: util.UNKNOWN, - Subsystems: []*pcidb.Product{}, - }, - Product: &pcidb.Product{ - ID: util.UNKNOWN, - Name: util.UNKNOWN, - Subsystems: []*pcidb.Product{}, - }, - Class: &pcidb.Class{ - ID: util.UNKNOWN, - Name: util.UNKNOWN, - Subclasses: []*pcidb.Subclass{}, - }, - Subclass: &pcidb.Subclass{ - ID: util.UNKNOWN, - Name: util.UNKNOWN, - ProgrammingInterfaces: []*pcidb.ProgrammingInterface{}, - }, - ProgrammingInterface: &pcidb.ProgrammingInterface{ - ID: util.UNKNOWN, - Name: util.UNKNOWN, - }, - } - // If an entity is found we get its data inside the standard structure - for _, description := range entities { - if id == description.PNPDeviceID { - device.Vendor.ID = description.Manufacturer - device.Vendor.Name = description.Manufacturer - device.Product.ID = description.Name - device.Product.Name = description.Description - break - } - } - return device -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/linuxdmi/dmi_linux.go b/vendor/github.com/jaypipes/ghw/pkg/linuxdmi/dmi_linux.go deleted file mode 100644 index 09398d36c8..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/linuxdmi/dmi_linux.go +++ /dev/null @@ -1,29 +0,0 @@ -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package linuxdmi - -import ( - "io/ioutil" - "path/filepath" - "strings" - - "github.com/jaypipes/ghw/pkg/context" - "github.com/jaypipes/ghw/pkg/linuxpath" - "github.com/jaypipes/ghw/pkg/util" -) - -func Item(ctx *context.Context, value string) string { - paths := linuxpath.New(ctx) - path := filepath.Join(paths.SysClassDMI, "id", value) - - b, err := ioutil.ReadFile(path) - if err != nil { - ctx.Warn("Unable to read %s: %s\n", value, err) - return util.UNKNOWN - } - - return strings.TrimSpace(string(b)) -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/linuxpath/path_linux.go b/vendor/github.com/jaypipes/ghw/pkg/linuxpath/path_linux.go deleted file mode 100644 index 0322f2e381..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/linuxpath/path_linux.go +++ /dev/null @@ -1,71 +0,0 @@ -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package linuxpath - -import ( - "fmt" - "path/filepath" - - "github.com/jaypipes/ghw/pkg/context" -) - -type Paths struct { - VarLog string - ProcMeminfo string - ProcCpuinfo string - SysKernelMMHugepages string - EtcMtab string - SysBlock string - SysDevicesSystemNode string - SysDevicesSystemMemory string - SysBusPciDevices string - SysClassDRM string - SysClassDMI string - SysClassNet string - RunUdevData string -} - -// New returns a new Paths struct containing filepath fields relative to the -// supplied Context -func New(ctx *context.Context) *Paths { - return &Paths{ - VarLog: filepath.Join(ctx.Chroot, "var", "log"), - ProcMeminfo: filepath.Join(ctx.Chroot, "proc", "meminfo"), - ProcCpuinfo: filepath.Join(ctx.Chroot, "proc", "cpuinfo"), - SysKernelMMHugepages: filepath.Join(ctx.Chroot, "sys", "kernel", "mm", "hugepages"), - EtcMtab: filepath.Join(ctx.Chroot, "etc", "mtab"), - SysBlock: filepath.Join(ctx.Chroot, "sys", "block"), - SysDevicesSystemNode: filepath.Join(ctx.Chroot, "sys", "devices", "system", "node"), - SysDevicesSystemMemory: filepath.Join(ctx.Chroot, "sys", "devices", "system", "memory"), - SysBusPciDevices: filepath.Join(ctx.Chroot, "sys", "bus", "pci", "devices"), - SysClassDRM: filepath.Join(ctx.Chroot, "sys", "class", "drm"), - SysClassDMI: filepath.Join(ctx.Chroot, "sys", "class", "dmi"), - SysClassNet: filepath.Join(ctx.Chroot, "sys", "class", "net"), - RunUdevData: filepath.Join(ctx.Chroot, "run", "udev", "data"), - } -} - -func (p *Paths) NodeCPU(nodeID int, lpID int) string { - return filepath.Join( - p.SysDevicesSystemNode, - fmt.Sprintf("node%d", nodeID), - fmt.Sprintf("cpu%d", lpID), - ) -} - -func (p *Paths) NodeCPUCache(nodeID int, lpID int) string { - return filepath.Join( - p.NodeCPU(nodeID, lpID), - "cache", - ) -} - -func (p *Paths) NodeCPUCacheIndex(nodeID int, lpID int, cacheIndex int) string { - return filepath.Join( - p.NodeCPUCache(nodeID, lpID), - fmt.Sprintf("index%d", cacheIndex), - ) -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/marshal/marshal.go b/vendor/github.com/jaypipes/ghw/pkg/marshal/marshal.go deleted file mode 100644 index e8f1bbeac9..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/marshal/marshal.go +++ /dev/null @@ -1,47 +0,0 @@ -// -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package marshal - -import ( - "encoding/json" - - "github.com/ghodss/yaml" - "github.com/jaypipes/ghw/pkg/context" -) - -// safeYAML returns a string after marshalling the supplied parameter into YAML -func SafeYAML(ctx *context.Context, p interface{}) string { - b, err := json.Marshal(p) - if err != nil { - ctx.Warn("error marshalling JSON: %s", err) - return "" - } - yb, err := yaml.JSONToYAML(b) - if err != nil { - ctx.Warn("error converting JSON to YAML: %s", err) - return "" - } - return string(yb) -} - -// safeJSON returns a string after marshalling the supplied parameter into -// JSON. Accepts an optional argument to trigger pretty/indented formatting of -// the JSON string -func SafeJSON(ctx *context.Context, p interface{}, indent bool) string { - var b []byte - var err error - if !indent { - b, err = json.Marshal(p) - } else { - b, err = json.MarshalIndent(&p, "", " ") - } - if err != nil { - ctx.Warn("error marshalling JSON: %s", err) - return "" - } - return string(b) -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/memory/memory.go b/vendor/github.com/jaypipes/ghw/pkg/memory/memory.go deleted file mode 100644 index 93605d2e5c..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/memory/memory.go +++ /dev/null @@ -1,80 +0,0 @@ -// -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package memory - -import ( - "fmt" - "math" - - "github.com/jaypipes/ghw/pkg/context" - "github.com/jaypipes/ghw/pkg/marshal" - "github.com/jaypipes/ghw/pkg/option" - "github.com/jaypipes/ghw/pkg/unitutil" - "github.com/jaypipes/ghw/pkg/util" -) - -type Module struct { - Label string `json:"label"` - Location string `json:"location"` - SerialNumber string `json:"serial_number"` - SizeBytes int64 `json:"size_bytes"` - Vendor string `json:"vendor"` -} - -type Info struct { - ctx *context.Context - TotalPhysicalBytes int64 `json:"total_physical_bytes"` - TotalUsableBytes int64 `json:"total_usable_bytes"` - // An array of sizes, in bytes, of memory pages supported by the host - SupportedPageSizes []uint64 `json:"supported_page_sizes"` - Modules []*Module `json:"modules"` -} - -func New(opts ...*option.Option) (*Info, error) { - ctx := context.New(opts...) - info := &Info{ctx: ctx} - if err := ctx.Do(info.load); err != nil { - return nil, err - } - return info, nil -} - -func (i *Info) String() string { - tpbs := util.UNKNOWN - if i.TotalPhysicalBytes > 0 { - tpb := i.TotalPhysicalBytes - unit, unitStr := unitutil.AmountString(tpb) - tpb = int64(math.Ceil(float64(i.TotalPhysicalBytes) / float64(unit))) - tpbs = fmt.Sprintf("%d%s", tpb, unitStr) - } - tubs := util.UNKNOWN - if i.TotalUsableBytes > 0 { - tub := i.TotalUsableBytes - unit, unitStr := unitutil.AmountString(tub) - tub = int64(math.Ceil(float64(i.TotalUsableBytes) / float64(unit))) - tubs = fmt.Sprintf("%d%s", tub, unitStr) - } - return fmt.Sprintf("memory (%s physical, %s usable)", tpbs, tubs) -} - -// simple private struct used to encapsulate memory information in a top-level -// "memory" YAML/JSON map/object key -type memoryPrinter struct { - Info *Info `json:"memory"` -} - -// YAMLString returns a string with the memory information formatted as YAML -// under a top-level "memory:" key -func (i *Info) YAMLString() string { - return marshal.SafeYAML(i.ctx, memoryPrinter{i}) -} - -// JSONString returns a string with the memory information formatted as JSON -// under a top-level "memory:" key -func (i *Info) JSONString(indent bool) string { - return marshal.SafeJSON(i.ctx, memoryPrinter{i}, indent) -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/memory/memory_cache.go b/vendor/github.com/jaypipes/ghw/pkg/memory/memory_cache.go deleted file mode 100644 index 5adbb9cd15..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/memory/memory_cache.go +++ /dev/null @@ -1,101 +0,0 @@ -// -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package memory - -import ( - "fmt" - "strconv" - "strings" - - "github.com/jaypipes/ghw/pkg/unitutil" -) - -type CacheType int - -const ( - CACHE_TYPE_UNIFIED CacheType = iota - CACHE_TYPE_INSTRUCTION - CACHE_TYPE_DATA -) - -var ( - memoryCacheTypeString = map[CacheType]string{ - CACHE_TYPE_UNIFIED: "Unified", - CACHE_TYPE_INSTRUCTION: "Instruction", - CACHE_TYPE_DATA: "Data", - } -) - -func (a CacheType) String() string { - return memoryCacheTypeString[a] -} - -// NOTE(jaypipes): since serialized output is as "official" as we're going to -// get, let's lowercase the string output when serializing, in order to -// "normalize" the expected serialized output -func (a CacheType) MarshalJSON() ([]byte, error) { - return []byte("\"" + strings.ToLower(a.String()) + "\""), nil -} - -type SortByCacheLevelTypeFirstProcessor []*Cache - -func (a SortByCacheLevelTypeFirstProcessor) Len() int { return len(a) } -func (a SortByCacheLevelTypeFirstProcessor) Swap(i, j int) { a[i], a[j] = a[j], a[i] } -func (a SortByCacheLevelTypeFirstProcessor) Less(i, j int) bool { - if a[i].Level < a[j].Level { - return true - } else if a[i].Level == a[j].Level { - if a[i].Type < a[j].Type { - return true - } else if a[i].Type == a[j].Type { - // NOTE(jaypipes): len(LogicalProcessors) is always >0 and is always - // sorted lowest LP ID to highest LP ID - return a[i].LogicalProcessors[0] < a[j].LogicalProcessors[0] - } - } - return false -} - -type SortByLogicalProcessorId []uint32 - -func (a SortByLogicalProcessorId) Len() int { return len(a) } -func (a SortByLogicalProcessorId) Swap(i, j int) { a[i], a[j] = a[j], a[i] } -func (a SortByLogicalProcessorId) Less(i, j int) bool { return a[i] < a[j] } - -type Cache struct { - Level uint8 `json:"level"` - Type CacheType `json:"type"` - SizeBytes uint64 `json:"size_bytes"` - // The set of logical processors (hardware threads) that have access to the - // cache - LogicalProcessors []uint32 `json:"logical_processors"` -} - -func (c *Cache) String() string { - sizeKb := c.SizeBytes / uint64(unitutil.KB) - typeStr := "" - if c.Type == CACHE_TYPE_INSTRUCTION { - typeStr = "i" - } else if c.Type == CACHE_TYPE_DATA { - typeStr = "d" - } - cacheIDStr := fmt.Sprintf("L%d%s", c.Level, typeStr) - processorMapStr := "" - if c.LogicalProcessors != nil { - lpStrings := make([]string, len(c.LogicalProcessors)) - for x, lpid := range c.LogicalProcessors { - lpStrings[x] = strconv.Itoa(int(lpid)) - } - processorMapStr = " shared with logical processors: " + strings.Join(lpStrings, ",") - } - return fmt.Sprintf( - "%s cache (%d KB)%s", - cacheIDStr, - sizeKb, - processorMapStr, - ) -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/memory/memory_cache_linux.go b/vendor/github.com/jaypipes/ghw/pkg/memory/memory_cache_linux.go deleted file mode 100644 index 88ab5e56ce..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/memory/memory_cache_linux.go +++ /dev/null @@ -1,188 +0,0 @@ -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package memory - -import ( - "errors" - "fmt" - "io/ioutil" - "os" - "path/filepath" - "sort" - "strconv" - "strings" - - "github.com/jaypipes/ghw/pkg/context" - "github.com/jaypipes/ghw/pkg/linuxpath" - "github.com/jaypipes/ghw/pkg/unitutil" -) - -func CachesForNode(ctx *context.Context, nodeID int) ([]*Cache, error) { - // The /sys/devices/node/nodeX directory contains a subdirectory called - // 'cpuX' for each logical processor assigned to the node. Each of those - // subdirectories containers a 'cache' subdirectory which contains a number - // of subdirectories beginning with 'index' and ending in the cache's - // internal 0-based identifier. Those subdirectories contain a number of - // files, including 'shared_cpu_list', 'size', and 'type' which we use to - // determine cache characteristics. - paths := linuxpath.New(ctx) - path := filepath.Join( - paths.SysDevicesSystemNode, - fmt.Sprintf("node%d", nodeID), - ) - caches := make(map[string]*Cache) - - files, err := ioutil.ReadDir(path) - if err != nil { - return nil, err - } - for _, file := range files { - filename := file.Name() - if !strings.HasPrefix(filename, "cpu") { - continue - } - if filename == "cpumap" || filename == "cpulist" { - // There are two files in the node directory that start with 'cpu' - // but are not subdirectories ('cpulist' and 'cpumap'). Ignore - // these files. - continue - } - // Grab the logical processor ID by cutting the integer from the - // /sys/devices/system/node/nodeX/cpuX filename - cpuPath := filepath.Join(path, filename) - lpID, _ := strconv.Atoi(filename[3:]) - - // Inspect the caches for each logical processor. There will be a - // /sys/devices/system/node/nodeX/cpuX/cache directory containing a - // number of directories beginning with the prefix "index" followed by - // a number. The number indicates the level of the cache, which - // indicates the "distance" from the processor. Each of these - // directories contains information about the size of that level of - // cache and the processors mapped to it. - cachePath := filepath.Join(cpuPath, "cache") - if _, err = os.Stat(cachePath); errors.Is(err, os.ErrNotExist) { - continue - } - cacheDirFiles, err := ioutil.ReadDir(cachePath) - if err != nil { - return nil, err - } - for _, cacheDirFile := range cacheDirFiles { - cacheDirFileName := cacheDirFile.Name() - if !strings.HasPrefix(cacheDirFileName, "index") { - continue - } - cacheIndex, _ := strconv.Atoi(cacheDirFileName[5:]) - - // The cache information is repeated for each node, so here, we - // just ensure that we only have a one Cache object for each - // unique combination of level, type and processor map - level := memoryCacheLevel(paths, nodeID, lpID, cacheIndex) - cacheType := memoryCacheType(paths, nodeID, lpID, cacheIndex) - sharedCpuMap := memoryCacheSharedCPUMap(paths, nodeID, lpID, cacheIndex) - cacheKey := fmt.Sprintf("%d-%d-%s", level, cacheType, sharedCpuMap) - - cache, exists := caches[cacheKey] - if !exists { - size := memoryCacheSize(paths, nodeID, lpID, level) - cache = &Cache{ - Level: uint8(level), - Type: cacheType, - SizeBytes: uint64(size) * uint64(unitutil.KB), - LogicalProcessors: make([]uint32, 0), - } - caches[cacheKey] = cache - } - cache.LogicalProcessors = append( - cache.LogicalProcessors, - uint32(lpID), - ) - } - } - - cacheVals := make([]*Cache, len(caches)) - x := 0 - for _, c := range caches { - // ensure the cache's processor set is sorted by logical process ID - sort.Sort(SortByLogicalProcessorId(c.LogicalProcessors)) - cacheVals[x] = c - x++ - } - - return cacheVals, nil -} - -func memoryCacheLevel(paths *linuxpath.Paths, nodeID int, lpID int, cacheIndex int) int { - levelPath := filepath.Join( - paths.NodeCPUCacheIndex(nodeID, lpID, cacheIndex), - "level", - ) - levelContents, err := ioutil.ReadFile(levelPath) - if err != nil { - _, _ = fmt.Fprintf(os.Stderr, "%s\n", err) - return -1 - } - // levelContents is now a []byte with the last byte being a newline - // character. Trim that off and convert the contents to an integer. - level, err := strconv.Atoi(string(levelContents[:len(levelContents)-1])) - if err != nil { - _, _ = fmt.Fprintf(os.Stderr, "Unable to parse int from %s\n", levelContents) - return -1 - } - return level -} - -func memoryCacheSize(paths *linuxpath.Paths, nodeID int, lpID int, cacheIndex int) int { - sizePath := filepath.Join( - paths.NodeCPUCacheIndex(nodeID, lpID, cacheIndex), - "size", - ) - sizeContents, err := ioutil.ReadFile(sizePath) - if err != nil { - _, _ = fmt.Fprintf(os.Stderr, "%s\n", err) - return -1 - } - // size comes as XK\n, so we trim off the K and the newline. - size, err := strconv.Atoi(string(sizeContents[:len(sizeContents)-2])) - if err != nil { - _, _ = fmt.Fprintf(os.Stderr, "Unable to parse int from %s\n", sizeContents) - return -1 - } - return size -} - -func memoryCacheType(paths *linuxpath.Paths, nodeID int, lpID int, cacheIndex int) CacheType { - typePath := filepath.Join( - paths.NodeCPUCacheIndex(nodeID, lpID, cacheIndex), - "type", - ) - cacheTypeContents, err := ioutil.ReadFile(typePath) - if err != nil { - _, _ = fmt.Fprintf(os.Stderr, "%s\n", err) - return CACHE_TYPE_UNIFIED - } - switch string(cacheTypeContents[:len(cacheTypeContents)-1]) { - case "Data": - return CACHE_TYPE_DATA - case "Instruction": - return CACHE_TYPE_INSTRUCTION - default: - return CACHE_TYPE_UNIFIED - } -} - -func memoryCacheSharedCPUMap(paths *linuxpath.Paths, nodeID int, lpID int, cacheIndex int) string { - scpuPath := filepath.Join( - paths.NodeCPUCacheIndex(nodeID, lpID, cacheIndex), - "shared_cpu_map", - ) - sharedCpuMap, err := ioutil.ReadFile(scpuPath) - if err != nil { - _, _ = fmt.Fprintf(os.Stderr, "%s\n", err) - return "" - } - return string(sharedCpuMap[:len(sharedCpuMap)-1]) -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/memory/memory_linux.go b/vendor/github.com/jaypipes/ghw/pkg/memory/memory_linux.go deleted file mode 100644 index 2fb85b71d6..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/memory/memory_linux.go +++ /dev/null @@ -1,237 +0,0 @@ -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package memory - -import ( - "bufio" - "compress/gzip" - "fmt" - "io" - "io/ioutil" - "os" - "path/filepath" - "regexp" - "strconv" - "strings" - - "github.com/jaypipes/ghw/pkg/linuxpath" - "github.com/jaypipes/ghw/pkg/unitutil" - "github.com/jaypipes/ghw/pkg/util" -) - -const ( - _WARN_CANNOT_DETERMINE_PHYSICAL_MEMORY = ` -Could not determine total physical bytes of memory. This may -be due to the host being a virtual machine or container with no -/var/log/syslog file or /sys/devices/system/memory directory, or -the current user may not have necessary privileges to read the syslog. -We are falling back to setting the total physical amount of memory to -the total usable amount of memory -` -) - -var ( - // System log lines will look similar to the following: - // ... kernel: [0.000000] Memory: 24633272K/25155024K ... - _REGEX_SYSLOG_MEMLINE = regexp.MustCompile(`Memory:\s+\d+K\/(\d+)K`) -) - -func (i *Info) load() error { - paths := linuxpath.New(i.ctx) - tub := memTotalUsableBytes(paths) - if tub < 1 { - return fmt.Errorf("Could not determine total usable bytes of memory") - } - i.TotalUsableBytes = tub - tpb := memTotalPhysicalBytes(paths) - i.TotalPhysicalBytes = tpb - if tpb < 1 { - i.ctx.Warn(_WARN_CANNOT_DETERMINE_PHYSICAL_MEMORY) - i.TotalPhysicalBytes = tub - } - i.SupportedPageSizes = memSupportedPageSizes(paths) - return nil -} - -func memTotalPhysicalBytes(paths *linuxpath.Paths) (total int64) { - defer func() { - // fallback to the syslog file approach in case of error - if total < 0 { - total = memTotalPhysicalBytesFromSyslog(paths) - } - }() - - // detect physical memory from /sys/devices/system/memory - dir := paths.SysDevicesSystemMemory - - // get the memory block size in byte in hexadecimal notation - blockSize := filepath.Join(dir, "block_size_bytes") - - d, err := ioutil.ReadFile(blockSize) - if err != nil { - return -1 - } - blockSizeBytes, err := strconv.ParseUint(strings.TrimSpace(string(d)), 16, 64) - if err != nil { - return -1 - } - - // iterate over memory's block /sys/devices/system/memory/memory*, - // if the memory block state is 'online' we increment the total - // with the memory block size to determine the amount of physical - // memory available on this system - sysMemory, err := filepath.Glob(filepath.Join(dir, "memory*")) - if err != nil { - return -1 - } else if sysMemory == nil { - return -1 - } - - for _, path := range sysMemory { - s, err := ioutil.ReadFile(filepath.Join(path, "state")) - if err != nil { - return -1 - } - if strings.TrimSpace(string(s)) != "online" { - continue - } - total += int64(blockSizeBytes) - } - - return total -} - -func memTotalPhysicalBytesFromSyslog(paths *linuxpath.Paths) int64 { - // In Linux, the total physical memory can be determined by looking at the - // output of dmidecode, however dmidecode requires root privileges to run, - // so instead we examine the system logs for startup information containing - // total physical memory and cache the results of this. - findPhysicalKb := func(line string) int64 { - matches := _REGEX_SYSLOG_MEMLINE.FindStringSubmatch(line) - if len(matches) == 2 { - i, err := strconv.Atoi(matches[1]) - if err != nil { - return -1 - } - return int64(i * 1024) - } - return -1 - } - - // /var/log will contain a file called syslog and 0 or more files called - // syslog.$NUMBER or syslog.$NUMBER.gz containing system log records. We - // search each, stopping when we match a system log record line that - // contains physical memory information. - logDir := paths.VarLog - logFiles, err := ioutil.ReadDir(logDir) - if err != nil { - return -1 - } - for _, file := range logFiles { - if strings.HasPrefix(file.Name(), "syslog") { - fullPath := filepath.Join(logDir, file.Name()) - unzip := strings.HasSuffix(file.Name(), ".gz") - var r io.ReadCloser - r, err = os.Open(fullPath) - if err != nil { - return -1 - } - defer util.SafeClose(r) - if unzip { - r, err = gzip.NewReader(r) - if err != nil { - return -1 - } - } - - scanner := bufio.NewScanner(r) - for scanner.Scan() { - line := scanner.Text() - size := findPhysicalKb(line) - if size > 0 { - return size - } - } - } - } - return -1 -} - -func memTotalUsableBytes(paths *linuxpath.Paths) int64 { - // In Linux, /proc/meminfo contains a set of memory-related amounts, with - // lines looking like the following: - // - // $ cat /proc/meminfo - // MemTotal: 24677596 kB - // MemFree: 21244356 kB - // MemAvailable: 22085432 kB - // ... - // HugePages_Total: 0 - // HugePages_Free: 0 - // HugePages_Rsvd: 0 - // HugePages_Surp: 0 - // ... - // - // It's worth noting that /proc/meminfo returns exact information, not - // "theoretical" information. For instance, on the above system, I have - // 24GB of RAM but MemTotal is indicating only around 23GB. This is because - // MemTotal contains the exact amount of *usable* memory after accounting - // for the kernel's resident memory size and a few reserved bits. For more - // information, see: - // - // https://www.kernel.org/doc/Documentation/filesystems/proc.txt - filePath := paths.ProcMeminfo - r, err := os.Open(filePath) - if err != nil { - return -1 - } - defer util.SafeClose(r) - - scanner := bufio.NewScanner(r) - for scanner.Scan() { - line := scanner.Text() - parts := strings.Fields(line) - key := strings.Trim(parts[0], ": \t") - if key != "MemTotal" { - continue - } - value, err := strconv.Atoi(strings.TrimSpace(parts[1])) - if err != nil { - return -1 - } - inKb := (len(parts) == 3 && strings.TrimSpace(parts[2]) == "kB") - if inKb { - value = value * int(unitutil.KB) - } - return int64(value) - } - return -1 -} - -func memSupportedPageSizes(paths *linuxpath.Paths) []uint64 { - // In Linux, /sys/kernel/mm/hugepages contains a directory per page size - // supported by the kernel. The directory name corresponds to the pattern - // 'hugepages-{pagesize}kb' - dir := paths.SysKernelMMHugepages - out := make([]uint64, 0) - - files, err := ioutil.ReadDir(dir) - if err != nil { - return out - } - for _, file := range files { - parts := strings.Split(file.Name(), "-") - sizeStr := parts[1] - // Cut off the 'kb' - sizeStr = sizeStr[0 : len(sizeStr)-2] - size, err := strconv.Atoi(sizeStr) - if err != nil { - return out - } - out = append(out, uint64(size*int(unitutil.KB))) - } - return out -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/memory/memory_stub.go b/vendor/github.com/jaypipes/ghw/pkg/memory/memory_stub.go deleted file mode 100644 index 26a28b0565..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/memory/memory_stub.go +++ /dev/null @@ -1,17 +0,0 @@ -// +build !linux,!windows -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package memory - -import ( - "runtime" - - "github.com/pkg/errors" -) - -func (i *Info) load() error { - return errors.New("mem.Info.load not implemented on " + runtime.GOOS) -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/memory/memory_windows.go b/vendor/github.com/jaypipes/ghw/pkg/memory/memory_windows.go deleted file mode 100644 index c3a3945ca9..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/memory/memory_windows.go +++ /dev/null @@ -1,72 +0,0 @@ -// -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package memory - -import ( - "github.com/StackExchange/wmi" - - "github.com/jaypipes/ghw/pkg/unitutil" -) - -const wqlOperatingSystem = "SELECT TotalVisibleMemorySize FROM Win32_OperatingSystem" - -type win32OperatingSystem struct { - TotalVisibleMemorySize *uint64 -} - -const wqlPhysicalMemory = "SELECT BankLabel, Capacity, DataWidth, Description, DeviceLocator, Manufacturer, Model, Name, PartNumber, PositionInRow, SerialNumber, Speed, Tag, TotalWidth FROM Win32_PhysicalMemory" - -type win32PhysicalMemory struct { - BankLabel *string - Capacity *uint64 - DataWidth *uint16 - Description *string - DeviceLocator *string - Manufacturer *string - Model *string - Name *string - PartNumber *string - PositionInRow *uint32 - SerialNumber *string - Speed *uint32 - Tag *string - TotalWidth *uint16 -} - -func (i *Info) load() error { - // Getting info from WMI - var win32OSDescriptions []win32OperatingSystem - if err := wmi.Query(wqlOperatingSystem, &win32OSDescriptions); err != nil { - return err - } - var win32MemDescriptions []win32PhysicalMemory - if err := wmi.Query(wqlPhysicalMemory, &win32MemDescriptions); err != nil { - return err - } - // We calculate total physical memory size by summing the DIMM sizes - var totalPhysicalBytes uint64 - i.Modules = make([]*Module, 0, len(win32MemDescriptions)) - for _, description := range win32MemDescriptions { - totalPhysicalBytes += *description.Capacity - i.Modules = append(i.Modules, &Module{ - Label: *description.BankLabel, - Location: *description.DeviceLocator, - SerialNumber: *description.SerialNumber, - SizeBytes: int64(*description.Capacity), - Vendor: *description.Manufacturer, - }) - } - var totalUsableBytes uint64 - for _, description := range win32OSDescriptions { - // TotalVisibleMemorySize is the amount of memory available for us by - // the operating system **in Kilobytes** - totalUsableBytes += *description.TotalVisibleMemorySize * uint64(unitutil.KB) - } - i.TotalUsableBytes = int64(totalUsableBytes) - i.TotalPhysicalBytes = int64(totalPhysicalBytes) - return nil -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/net/net.go b/vendor/github.com/jaypipes/ghw/pkg/net/net.go deleted file mode 100644 index 8994d112ec..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/net/net.go +++ /dev/null @@ -1,83 +0,0 @@ -// -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package net - -import ( - "fmt" - - "github.com/jaypipes/ghw/pkg/context" - "github.com/jaypipes/ghw/pkg/marshal" - "github.com/jaypipes/ghw/pkg/option" -) - -type NICCapability struct { - Name string `json:"name"` - IsEnabled bool `json:"is_enabled"` - CanEnable bool `json:"can_enable"` -} - -type NIC struct { - Name string `json:"name"` - MacAddress string `json:"mac_address"` - IsVirtual bool `json:"is_virtual"` - Capabilities []*NICCapability `json:"capabilities"` - PCIAddress *string `json:"pci_address,omitempty"` - // TODO(fromani): add other hw addresses (USB) when we support them -} - -func (n *NIC) String() string { - isVirtualStr := "" - if n.IsVirtual { - isVirtualStr = " (virtual)" - } - return fmt.Sprintf( - "%s%s", - n.Name, - isVirtualStr, - ) -} - -type Info struct { - ctx *context.Context - NICs []*NIC `json:"nics"` -} - -// New returns a pointer to an Info struct that contains information about the -// network interface controllers (NICs) on the host system -func New(opts ...*option.Option) (*Info, error) { - ctx := context.New(opts...) - info := &Info{ctx: ctx} - if err := ctx.Do(info.load); err != nil { - return nil, err - } - return info, nil -} - -func (i *Info) String() string { - return fmt.Sprintf( - "net (%d NICs)", - len(i.NICs), - ) -} - -// simple private struct used to encapsulate net information in a -// top-level "net" YAML/JSON map/object key -type netPrinter struct { - Info *Info `json:"network"` -} - -// YAMLString returns a string with the net information formatted as YAML -// under a top-level "net:" key -func (i *Info) YAMLString() string { - return marshal.SafeYAML(i.ctx, netPrinter{i}) -} - -// JSONString returns a string with the net information formatted as JSON -// under a top-level "net:" key -func (i *Info) JSONString(indent bool) string { - return marshal.SafeJSON(i.ctx, netPrinter{i}, indent) -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/net/net_linux.go b/vendor/github.com/jaypipes/ghw/pkg/net/net_linux.go deleted file mode 100644 index 1b338dfaf4..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/net/net_linux.go +++ /dev/null @@ -1,222 +0,0 @@ -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package net - -import ( - "bufio" - "bytes" - "fmt" - "io/ioutil" - "os" - "os/exec" - "path/filepath" - "strings" - - "github.com/jaypipes/ghw/pkg/context" - "github.com/jaypipes/ghw/pkg/linuxpath" -) - -const ( - _WARN_ETHTOOL_NOT_INSTALLED = `ethtool not installed. Cannot grab NIC capabilities` -) - -func (i *Info) load() error { - i.NICs = nics(i.ctx) - return nil -} - -func nics(ctx *context.Context) []*NIC { - nics := make([]*NIC, 0) - - paths := linuxpath.New(ctx) - files, err := ioutil.ReadDir(paths.SysClassNet) - if err != nil { - return nics - } - - etAvailable := ctx.EnableTools - if etAvailable { - if etInstalled := ethtoolInstalled(); !etInstalled { - ctx.Warn(_WARN_ETHTOOL_NOT_INSTALLED) - etAvailable = false - } - } - - for _, file := range files { - filename := file.Name() - // Ignore loopback... - if filename == "lo" { - continue - } - - netPath := filepath.Join(paths.SysClassNet, filename) - dest, _ := os.Readlink(netPath) - isVirtual := false - if strings.Contains(dest, "devices/virtual/net") { - isVirtual = true - } - - nic := &NIC{ - Name: filename, - IsVirtual: isVirtual, - } - - mac := netDeviceMacAddress(paths, filename) - nic.MacAddress = mac - if etAvailable { - nic.Capabilities = netDeviceCapabilities(ctx, filename) - } else { - nic.Capabilities = []*NICCapability{} - } - - nic.PCIAddress = netDevicePCIAddress(paths.SysClassNet, filename) - - nics = append(nics, nic) - } - return nics -} - -func netDeviceMacAddress(paths *linuxpath.Paths, dev string) string { - // Instead of use udevadm, we can get the device's MAC address by examing - // the /sys/class/net/$DEVICE/address file in sysfs. However, for devices - // that have addr_assign_type != 0, return None since the MAC address is - // random. - aatPath := filepath.Join(paths.SysClassNet, dev, "addr_assign_type") - contents, err := ioutil.ReadFile(aatPath) - if err != nil { - return "" - } - if strings.TrimSpace(string(contents)) != "0" { - return "" - } - addrPath := filepath.Join(paths.SysClassNet, dev, "address") - contents, err = ioutil.ReadFile(addrPath) - if err != nil { - return "" - } - return strings.TrimSpace(string(contents)) -} - -func ethtoolInstalled() bool { - _, err := exec.LookPath("ethtool") - return err == nil -} - -func netDeviceCapabilities(ctx *context.Context, dev string) []*NICCapability { - caps := make([]*NICCapability, 0) - path, _ := exec.LookPath("ethtool") - cmd := exec.Command(path, "-k", dev) - var out bytes.Buffer - cmd.Stdout = &out - err := cmd.Run() - if err != nil { - msg := fmt.Sprintf("could not grab NIC capabilities for %s: %s", dev, err) - ctx.Warn(msg) - return caps - } - - // The out variable will now contain something that looks like the - // following. - // - // Features for enp58s0f1: - // rx-checksumming: on - // tx-checksumming: off - // tx-checksum-ipv4: off - // tx-checksum-ip-generic: off [fixed] - // tx-checksum-ipv6: off - // tx-checksum-fcoe-crc: off [fixed] - // tx-checksum-sctp: off [fixed] - // scatter-gather: off - // tx-scatter-gather: off - // tx-scatter-gather-fraglist: off [fixed] - // tcp-segmentation-offload: off - // tx-tcp-segmentation: off - // tx-tcp-ecn-segmentation: off [fixed] - // tx-tcp-mangleid-segmentation: off - // tx-tcp6-segmentation: off - // < snipped > - scanner := bufio.NewScanner(&out) - // Skip the first line... - scanner.Scan() - for scanner.Scan() { - line := strings.TrimPrefix(scanner.Text(), "\t") - caps = append(caps, netParseEthtoolFeature(line)) - } - return caps -} - -// netParseEthtoolFeature parses a line from the ethtool -k output and returns -// a NICCapability. -// -// The supplied line will look like the following: -// -// tx-checksum-ip-generic: off [fixed] -// -// [fixed] indicates that the feature may not be turned on/off. Note: it makes -// no difference whether a privileged user runs `ethtool -k` when determining -// whether [fixed] appears for a feature. -func netParseEthtoolFeature(line string) *NICCapability { - parts := strings.Fields(line) - cap := strings.TrimSuffix(parts[0], ":") - enabled := parts[1] == "on" - fixed := len(parts) == 3 && parts[2] == "[fixed]" - return &NICCapability{ - Name: cap, - IsEnabled: enabled, - CanEnable: !fixed, - } -} - -func netDevicePCIAddress(netDevDir, netDevName string) *string { - // what we do here is not that hard in the end: we need to navigate the sysfs - // up to the directory belonging to the device backing the network interface. - // we can make few relatively safe assumptions, but the safest way is follow - // the right links. And so we go. - // First of all, knowing the network device name we need to resolve the backing - // device path to its full sysfs path. - // say we start with netDevDir="/sys/class/net" and netDevName="enp0s31f6" - netPath := filepath.Join(netDevDir, netDevName) - dest, err := os.Readlink(netPath) - if err != nil { - // bail out with empty value - return nil - } - // now we have something like dest="../../devices/pci0000:00/0000:00:1f.6/net/enp0s31f6" - // remember the path is relative to netDevDir="/sys/class/net" - - netDev := filepath.Clean(filepath.Join(netDevDir, dest)) - // so we clean "/sys/class/net/../../devices/pci0000:00/0000:00:1f.6/net/enp0s31f6" - // leading to "/sys/devices/pci0000:00/0000:00:1f.6/net/enp0s31f6" - // still not there. We need to access the data of the pci device. So we jump into the path - // linked to the "device" pseudofile - dest, err = os.Readlink(filepath.Join(netDev, "device")) - if err != nil { - // bail out with empty value - return nil - } - // we expect something like="../../../0000:00:1f.6" - - devPath := filepath.Clean(filepath.Join(netDev, dest)) - // so we clean "/sys/devices/pci0000:00/0000:00:1f.6/net/enp0s31f6/../../../0000:00:1f.6" - // leading to "/sys/devices/pci0000:00/0000:00:1f.6/" - // finally here! - - // to which bus is this device connected to? - dest, err = os.Readlink(filepath.Join(devPath, "subsystem")) - if err != nil { - // bail out with empty value - return nil - } - // ok, this is hacky, but since we need the last *two* path components and we know we - // are running on linux... - if !strings.HasSuffix(dest, "/bus/pci") { - // unsupported and unexpected bus! - return nil - } - - pciAddr := filepath.Base(devPath) - return &pciAddr -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/net/net_stub.go b/vendor/github.com/jaypipes/ghw/pkg/net/net_stub.go deleted file mode 100644 index a19b769992..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/net/net_stub.go +++ /dev/null @@ -1,17 +0,0 @@ -// +build !linux,!windows -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package net - -import ( - "runtime" - - "github.com/pkg/errors" -) - -func (i *Info) load() error { - return errors.New("netFillInfo not implemented on " + runtime.GOOS) -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/net/net_windows.go b/vendor/github.com/jaypipes/ghw/pkg/net/net_windows.go deleted file mode 100644 index 70d0995857..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/net/net_windows.go +++ /dev/null @@ -1,65 +0,0 @@ -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package net - -import ( - "strings" - - "github.com/StackExchange/wmi" -) - -const wqlNetworkAdapter = "SELECT Description, DeviceID, Index, InterfaceIndex, MACAddress, Manufacturer, Name, NetConnectionID, ProductName, ServiceName FROM Win32_NetworkAdapter" - -type win32NetworkAdapter struct { - Description *string - DeviceID *string - Index *uint32 - InterfaceIndex *uint32 - MACAddress *string - Manufacturer *string - Name *string - NetConnectionID *string - ProductName *string - ServiceName *string -} - -func (i *Info) load() error { - // Getting info from WMI - var win32NetDescriptions []win32NetworkAdapter - if err := wmi.Query(wqlNetworkAdapter, &win32NetDescriptions); err != nil { - return err - } - - i.NICs = nics(win32NetDescriptions) - return nil -} - -func nics(win32NetDescriptions []win32NetworkAdapter) []*NIC { - // Converting into standard structures - nics := make([]*NIC, 0) - for _, nicDescription := range win32NetDescriptions { - nic := &NIC{ - Name: netDeviceName(nicDescription), - MacAddress: *nicDescription.MACAddress, - IsVirtual: false, - Capabilities: []*NICCapability{}, - } - // Appenging NIC to NICs - nics = append(nics, nic) - } - - return nics -} - -func netDeviceName(description win32NetworkAdapter) string { - var name string - if strings.TrimSpace(*description.NetConnectionID) != "" { - name = *description.NetConnectionID + " - " + *description.Description - } else { - name = *description.Description - } - return name -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/option/option.go b/vendor/github.com/jaypipes/ghw/pkg/option/option.go deleted file mode 100644 index 0af8b4cbe6..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/option/option.go +++ /dev/null @@ -1,227 +0,0 @@ -// -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package option - -import ( - "io" - "io/ioutil" - "log" - "os" -) - -const ( - defaultChroot = "/" - envKeyChroot = "GHW_CHROOT" - envKeyDisableWarnings = "GHW_DISABLE_WARNINGS" - envKeyDisableTools = "GHW_DISABLE_TOOLS" - envKeySnapshotPath = "GHW_SNAPSHOT_PATH" - envKeySnapshotRoot = "GHW_SNAPSHOT_ROOT" - envKeySnapshotExclusive = "GHW_SNAPSHOT_EXCLUSIVE" - envKeySnapshotPreserve = "GHW_SNAPSHOT_PRESERVE" -) - -// Alerter emits warnings about undesirable but recoverable errors. -// We use a subset of a logger interface only to emit warnings, and -// `Warninger` sounded ugly. -type Alerter interface { - Printf(format string, v ...interface{}) -} - -var ( - NullAlerter = log.New(ioutil.Discard, "", 0) -) - -// EnvOrDefaultAlerter returns the default instance ghw will use to emit -// its warnings. ghw will emit warnings to stderr by default unless the -// environs variable GHW_DISABLE_WARNINGS is specified; in the latter case -// all warning will be suppressed. -func EnvOrDefaultAlerter() Alerter { - var dest io.Writer - if _, exists := os.LookupEnv(envKeyDisableWarnings); exists { - dest = ioutil.Discard - } else { - // default - dest = os.Stderr - } - return log.New(dest, "", 0) -} - -// EnvOrDefaultChroot returns the value of the GHW_CHROOT environs variable or -// the default value of "/" if not set -func EnvOrDefaultChroot() string { - // Grab options from the environs by default - if val, exists := os.LookupEnv(envKeyChroot); exists { - return val - } - return defaultChroot -} - -// EnvOrDefaultSnapshotPath returns the value of the GHW_SNAPSHOT_PATH environs variable -// or the default value of "" (disable snapshot consumption) if not set -func EnvOrDefaultSnapshotPath() string { - if val, exists := os.LookupEnv(envKeySnapshotPath); exists { - return val - } - return "" // default is no snapshot -} - -// EnvOrDefaultSnapshotRoot returns the value of the the GHW_SNAPSHOT_ROOT environs variable -// or the default value of "" (self-manage the snapshot unpack directory, if relevant) if not set -func EnvOrDefaultSnapshotRoot() string { - if val, exists := os.LookupEnv(envKeySnapshotRoot); exists { - return val - } - return "" // default is to self-manage the snapshot directory -} - -// EnvOrDefaultSnapshotExclusive returns the value of the GHW_SNAPSHOT_EXCLUSIVE environs variable -// or the default value of false if not set -func EnvOrDefaultSnapshotExclusive() bool { - if _, exists := os.LookupEnv(envKeySnapshotExclusive); exists { - return true - } - return false -} - -// EnvOrDefaultSnapshotPreserve returns the value of the GHW_SNAPSHOT_PRESERVE environs variable -// or the default value of false if not set -func EnvOrDefaultSnapshotPreserve() bool { - if _, exists := os.LookupEnv(envKeySnapshotPreserve); exists { - return true - } - return false -} - -// EnvOrDefaultTools return true if ghw should use external tools to augment the data collected -// from sysfs. Most users want to do this most of time, so this is enabled by default. -// Users consuming snapshots may want to opt out, thus they can set the GHW_DISABLE_TOOLS -// environs variable to any value to make ghw skip calling external tools even if they are available. -func EnvOrDefaultTools() bool { - if _, exists := os.LookupEnv(envKeyDisableTools); exists { - return false - } - return true -} - -// Option is used to represent optionally-configured settings. Each field is a -// pointer to some concrete value so that we can tell when something has been -// set or left unset. -type Option struct { - // To facilitate querying of sysfs filesystems that are bind-mounted to a - // non-default root mountpoint, we allow users to set the GHW_CHROOT environ - // vairable to an alternate mountpoint. For instance, assume that the user of - // ghw is a Golang binary being executed from an application container that has - // certain host filesystems bind-mounted into the container at /host. The user - // would ensure the GHW_CHROOT environ variable is set to "/host" and ghw will - // build its paths from that location instead of / - Chroot *string - - // Snapshot contains options for handling ghw snapshots - Snapshot *SnapshotOptions - - // Alerter contains the target for ghw warnings - Alerter Alerter - - // EnableTools optionally request ghw to not call any external program to learn - // about the hardware. The default is to use such tools if available. - EnableTools *bool -} - -// SnapshotOptions contains options for handling of ghw snapshots -type SnapshotOptions struct { - // Path allows users to specify a snapshot (captured using ghw-snapshot) to be - // automatically consumed. Users need to supply the path of the snapshot, and - // ghw will take care of unpacking it on a temporary directory. - // Set the environment variable "GHW_SNAPSHOT_PRESERVE" to make ghw skip the cleanup - // stage and keep the unpacked snapshot in the temporary directory. - Path string - // Root is the directory on which the snapshot must be unpacked. This allows - // the users to manage their snapshot directory instead of ghw doing that on - // their behalf. Relevant only if SnapshotPath is given. - Root *string - // Exclusive tells ghw if the given directory should be considered of exclusive - // usage of ghw or not If the user provides a Root. If the flag is set, ghw will - // unpack the snapshot in the given SnapshotRoot iff the directory is empty; otherwise - // any existing content will be left untouched and the unpack stage will exit silently. - // As additional side effect, give both this option and SnapshotRoot to make each - // context try to unpack the snapshot only once. - Exclusive bool -} - -func WithChroot(dir string) *Option { - return &Option{Chroot: &dir} -} - -// WithSnapshot sets snapshot-processing options for a ghw run -func WithSnapshot(opts SnapshotOptions) *Option { - return &Option{ - Snapshot: &opts, - } -} - -// WithAlerter sets alerting options for ghw -func WithAlerter(alerter Alerter) *Option { - return &Option{ - Alerter: alerter, - } -} - -// WithNullAlerter sets No-op alerting options for ghw -func WithNullAlerter() *Option { - return &Option{ - Alerter: NullAlerter, - } -} - -// WithDisableTools sets enables or prohibts ghw to call external tools to discover hardware capabilities. -func WithDisableTools() *Option { - false_ := false - return &Option{EnableTools: &false_} -} - -// There is intentionally no Option related to GHW_SNAPSHOT_PRESERVE because we see that as -// a debug/troubleshoot aid more something users wants to do regularly. -// Hence we allow that only via the environment variable for the time being. - -func Merge(opts ...*Option) *Option { - merged := &Option{} - for _, opt := range opts { - if opt.Chroot != nil { - merged.Chroot = opt.Chroot - } - if opt.Snapshot != nil { - merged.Snapshot = opt.Snapshot - } - if opt.Alerter != nil { - merged.Alerter = opt.Alerter - } - if opt.EnableTools != nil { - merged.EnableTools = opt.EnableTools - } - } - // Set the default value if missing from mergeOpts - if merged.Chroot == nil { - chroot := EnvOrDefaultChroot() - merged.Chroot = &chroot - } - if merged.Alerter == nil { - merged.Alerter = EnvOrDefaultAlerter() - } - if merged.Snapshot == nil { - snapRoot := EnvOrDefaultSnapshotRoot() - merged.Snapshot = &SnapshotOptions{ - Path: EnvOrDefaultSnapshotPath(), - Root: &snapRoot, - Exclusive: EnvOrDefaultSnapshotExclusive(), - } - } - if merged.EnableTools == nil { - enabled := EnvOrDefaultTools() - merged.EnableTools = &enabled - } - return merged -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/pci/address/address.go b/vendor/github.com/jaypipes/ghw/pkg/pci/address/address.go deleted file mode 100644 index 7b1360536e..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/pci/address/address.go +++ /dev/null @@ -1,55 +0,0 @@ -// -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package address - -import ( - "regexp" - "strings" -) - -var ( - regexAddress *regexp.Regexp = regexp.MustCompile( - `^(([0-9a-f]{0,4}):)?([0-9a-f]{2}):([0-9a-f]{2})\.([0-9a-f]{1})$`, - ) -) - -type Address struct { - Domain string - Bus string - Slot string - Function string -} - -// String() returns the canonical [D]BSF representation of this Address -func (addr *Address) String() string { - return addr.Domain + ":" + addr.Bus + ":" + addr.Slot + "." + addr.Function -} - -// Given a string address, returns a complete Address struct, filled in with -// domain, bus, slot and function components. The address string may either -// be in $BUS:$SLOT.$FUNCTION (BSF) format or it can be a full PCI address -// that includes the 4-digit $DOMAIN information as well: -// $DOMAIN:$BUS:$SLOT.$FUNCTION. -// -// Returns "" if the address string wasn't a valid PCI address. -func FromString(address string) *Address { - addrLowered := strings.ToLower(address) - matches := regexAddress.FindStringSubmatch(addrLowered) - if len(matches) == 6 { - dom := "0000" - if matches[1] != "" { - dom = matches[2] - } - return &Address{ - Domain: dom, - Bus: matches[3], - Slot: matches[4], - Function: matches[5], - } - } - return nil -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/pci/pci.go b/vendor/github.com/jaypipes/ghw/pkg/pci/pci.go deleted file mode 100644 index c8176e6875..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/pci/pci.go +++ /dev/null @@ -1,206 +0,0 @@ -// -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package pci - -import ( - "encoding/json" - "fmt" - "regexp" - - "github.com/jaypipes/pcidb" - - "github.com/jaypipes/ghw/pkg/context" - "github.com/jaypipes/ghw/pkg/marshal" - "github.com/jaypipes/ghw/pkg/option" - pciaddr "github.com/jaypipes/ghw/pkg/pci/address" - "github.com/jaypipes/ghw/pkg/topology" - "github.com/jaypipes/ghw/pkg/util" -) - -// backward compatibility, to be removed in 1.0.0 -type Address pciaddr.Address - -// backward compatibility, to be removed in 1.0.0 -var AddressFromString = pciaddr.FromString - -var ( - regexAddress *regexp.Regexp = regexp.MustCompile( - `^(([0-9a-f]{0,4}):)?([0-9a-f]{2}):([0-9a-f]{2})\.([0-9a-f]{1})$`, - ) -) - -type Device struct { - // The PCI address of the device - Address string `json:"address"` - Vendor *pcidb.Vendor `json:"vendor"` - Product *pcidb.Product `json:"product"` - Revision string `json:"revision"` - Subsystem *pcidb.Product `json:"subsystem"` - // optional subvendor/sub-device information - Class *pcidb.Class `json:"class"` - // optional sub-class for the device - Subclass *pcidb.Subclass `json:"subclass"` - // optional programming interface - ProgrammingInterface *pcidb.ProgrammingInterface `json:"programming_interface"` - // Topology node that the PCI device is affined to. Will be nil if the - // architecture is not NUMA. - Node *topology.Node `json:"node,omitempty"` -} - -type devIdent struct { - ID string `json:"id"` - Name string `json:"name"` -} - -type devMarshallable struct { - Address string `json:"address"` - Vendor devIdent `json:"vendor"` - Product devIdent `json:"product"` - Revision string `json:"revision"` - Subsystem devIdent `json:"subsystem"` - Class devIdent `json:"class"` - Subclass devIdent `json:"subclass"` - Interface devIdent `json:"programming_interface"` -} - -// NOTE(jaypipes) Device has a custom JSON marshaller because we don't want -// to serialize the entire PCIDB information for the Vendor (which includes all -// of the vendor's products, etc). Instead, we simply serialize the ID and -// human-readable name of the vendor, product, class, etc. -func (d *Device) MarshalJSON() ([]byte, error) { - dm := devMarshallable{ - Address: d.Address, - Vendor: devIdent{ - ID: d.Vendor.ID, - Name: d.Vendor.Name, - }, - Product: devIdent{ - ID: d.Product.ID, - Name: d.Product.Name, - }, - Revision: d.Revision, - Subsystem: devIdent{ - ID: d.Subsystem.ID, - Name: d.Subsystem.Name, - }, - Class: devIdent{ - ID: d.Class.ID, - Name: d.Class.Name, - }, - Subclass: devIdent{ - ID: d.Subclass.ID, - Name: d.Subclass.Name, - }, - Interface: devIdent{ - ID: d.ProgrammingInterface.ID, - Name: d.ProgrammingInterface.Name, - }, - } - return json.Marshal(dm) -} - -func (d *Device) String() string { - vendorName := util.UNKNOWN - if d.Vendor != nil { - vendorName = d.Vendor.Name - } - productName := util.UNKNOWN - if d.Product != nil { - productName = d.Product.Name - } - className := util.UNKNOWN - if d.Class != nil { - className = d.Class.Name - } - return fmt.Sprintf( - "%s -> class: '%s' vendor: '%s' product: '%s'", - d.Address, - className, - vendorName, - productName, - ) -} - -type Info struct { - arch topology.Architecture - ctx *context.Context - // All PCI devices on the host system - Devices []*Device - // hash of class ID -> class information - // DEPRECATED. Will be removed in v1.0. Please use - // github.com/jaypipes/pcidb to explore PCIDB information - Classes map[string]*pcidb.Class `json:"-"` - // hash of vendor ID -> vendor information - // DEPRECATED. Will be removed in v1.0. Please use - // github.com/jaypipes/pcidb to explore PCIDB information - Vendors map[string]*pcidb.Vendor `json:"-"` - // hash of vendor ID + product/device ID -> product information - // DEPRECATED. Will be removed in v1.0. Please use - // github.com/jaypipes/pcidb to explore PCIDB information - Products map[string]*pcidb.Product `json:"-"` -} - -func (i *Info) String() string { - return fmt.Sprintf("PCI (%d devices)", len(i.Devices)) -} - -// New returns a pointer to an Info struct that contains information about the -// PCI devices on the host system -func New(opts ...*option.Option) (*Info, error) { - return NewWithContext(context.New(opts...)) -} - -// NewWithContext returns a pointer to an Info struct that contains information about -// the PCI devices on the host system. Use this function when you want to consume -// the topology package from another package (e.g. gpu) -func NewWithContext(ctx *context.Context) (*Info, error) { - // by default we don't report NUMA information; - // we will only if are sure we are running on NUMA architecture - arch := topology.ARCHITECTURE_SMP - topo, err := topology.NewWithContext(ctx) - if err == nil { - arch = topo.Architecture - } else { - ctx.Warn("error detecting system topology: %v", err) - } - info := &Info{ - arch: arch, - ctx: ctx, - } - if err := ctx.Do(info.load); err != nil { - return nil, err - } - return info, nil -} - -// lookupDevice gets a device from cached data -func (info *Info) lookupDevice(address string) *Device { - for _, dev := range info.Devices { - if dev.Address == address { - return dev - } - } - return nil -} - -// simple private struct used to encapsulate PCI information in a top-level -// "pci" YAML/JSON map/object key -type pciPrinter struct { - Info *Info `json:"pci"` -} - -// YAMLString returns a string with the PCI information formatted as YAML -// under a top-level "pci:" key -func (i *Info) YAMLString() string { - return marshal.SafeYAML(i.ctx, pciPrinter{i}) -} - -// JSONString returns a string with the PCI information formatted as JSON -// under a top-level "pci:" key -func (i *Info) JSONString(indent bool) string { - return marshal.SafeJSON(i.ctx, pciPrinter{i}, indent) -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/pci/pci_linux.go b/vendor/github.com/jaypipes/ghw/pkg/pci/pci_linux.go deleted file mode 100644 index 4c6e34a6ae..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/pci/pci_linux.go +++ /dev/null @@ -1,378 +0,0 @@ -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package pci - -import ( - "io/ioutil" - "os" - "path/filepath" - "strings" - - "github.com/jaypipes/pcidb" - - "github.com/jaypipes/ghw/pkg/context" - "github.com/jaypipes/ghw/pkg/linuxpath" - pciaddr "github.com/jaypipes/ghw/pkg/pci/address" - "github.com/jaypipes/ghw/pkg/topology" - "github.com/jaypipes/ghw/pkg/util" -) - -func (i *Info) load() error { - db, err := pcidb.New(pcidb.WithChroot(i.ctx.Chroot)) - if err != nil { - return err - } - i.Classes = db.Classes - i.Vendors = db.Vendors - i.Products = db.Products - i.Devices = i.ListDevices() - return nil -} - -func getDeviceModaliasPath(ctx *context.Context, address string) string { - paths := linuxpath.New(ctx) - pciAddr := pciaddr.FromString(address) - if pciAddr == nil { - return "" - } - return filepath.Join( - paths.SysBusPciDevices, - pciAddr.Domain+":"+pciAddr.Bus+":"+pciAddr.Slot+"."+pciAddr.Function, - "modalias", - ) -} - -func getDeviceRevision(ctx *context.Context, address string) string { - paths := linuxpath.New(ctx) - pciAddr := pciaddr.FromString(address) - if pciAddr == nil { - return "" - } - revisionPath := filepath.Join( - paths.SysBusPciDevices, - pciAddr.String(), - "revision", - ) - - if _, err := os.Stat(revisionPath); err != nil { - return "" - } - revision, err := ioutil.ReadFile(revisionPath) - if err != nil { - return "" - } - return strings.TrimSpace(string(revision)) -} - -func getDeviceNUMANode(ctx *context.Context, address string) *topology.Node { - paths := linuxpath.New(ctx) - pciAddr := AddressFromString(address) - if pciAddr == nil { - return nil - } - numaNodePath := filepath.Join(paths.SysBusPciDevices, pciAddr.String(), "numa_node") - - if _, err := os.Stat(numaNodePath); err != nil { - return nil - } - - nodeIdx := util.SafeIntFromFile(ctx, numaNodePath) - if nodeIdx == -1 { - return nil - } - - return &topology.Node{ - ID: nodeIdx, - } -} - -type deviceModaliasInfo struct { - vendorID string - productID string - subproductID string - subvendorID string - classID string - subclassID string - progIfaceID string -} - -func parseModaliasFile(fp string) *deviceModaliasInfo { - if _, err := os.Stat(fp); err != nil { - return nil - } - data, err := ioutil.ReadFile(fp) - if err != nil { - return nil - } - - return parseModaliasData(string(data)) -} - -func parseModaliasData(data string) *deviceModaliasInfo { - // The modalias file is an encoded file that looks like this: - // - // $ cat /sys/devices/pci0000\:00/0000\:00\:03.0/0000\:03\:00.0/modalias - // pci:v000010DEd00001C82sv00001043sd00008613bc03sc00i00 - // - // It is interpreted like so: - // - // pci: -- ignore - // v000010DE -- PCI vendor ID - // d00001C82 -- PCI device ID (the product/model ID) - // sv00001043 -- PCI subsystem vendor ID - // sd00008613 -- PCI subsystem device ID (subdevice product/model ID) - // bc03 -- PCI base class - // sc00 -- PCI subclass - // i00 -- programming interface - vendorID := strings.ToLower(data[9:13]) - productID := strings.ToLower(data[18:22]) - subvendorID := strings.ToLower(data[28:32]) - subproductID := strings.ToLower(data[38:42]) - classID := data[44:46] - subclassID := data[48:50] - progIfaceID := data[51:53] - return &deviceModaliasInfo{ - vendorID: vendorID, - productID: productID, - subproductID: subproductID, - subvendorID: subvendorID, - classID: classID, - subclassID: subclassID, - progIfaceID: progIfaceID, - } -} - -// Returns a pointer to a pcidb.Vendor struct matching the supplied vendor -// ID string. If no such vendor ID string could be found, returns the -// pcidb.Vendor struct populated with "unknown" vendor Name attribute and -// empty Products attribute. -func findPCIVendor(info *Info, vendorID string) *pcidb.Vendor { - vendor := info.Vendors[vendorID] - if vendor == nil { - return &pcidb.Vendor{ - ID: vendorID, - Name: util.UNKNOWN, - Products: []*pcidb.Product{}, - } - } - return vendor -} - -// Returns a pointer to a pcidb.Product struct matching the supplied vendor -// and product ID strings. If no such product could be found, returns the -// pcidb.Product struct populated with "unknown" product Name attribute and -// empty Subsystems attribute. -func findPCIProduct( - info *Info, - vendorID string, - productID string, -) *pcidb.Product { - product := info.Products[vendorID+productID] - if product == nil { - return &pcidb.Product{ - ID: productID, - Name: util.UNKNOWN, - Subsystems: []*pcidb.Product{}, - } - } - return product -} - -// Returns a pointer to a pcidb.Product struct matching the supplied vendor, -// product, subvendor and subproduct ID strings. If no such product could be -// found, returns the pcidb.Product struct populated with "unknown" product -// Name attribute and empty Subsystems attribute. -func findPCISubsystem( - info *Info, - vendorID string, - productID string, - subvendorID string, - subproductID string, -) *pcidb.Product { - product := info.Products[vendorID+productID] - subvendor := info.Vendors[subvendorID] - if subvendor != nil && product != nil { - for _, p := range product.Subsystems { - if p.ID == subproductID { - return p - } - } - } - return &pcidb.Product{ - VendorID: subvendorID, - ID: subproductID, - Name: util.UNKNOWN, - } -} - -// Returns a pointer to a pcidb.Class struct matching the supplied class ID -// string. If no such class ID string could be found, returns the -// pcidb.Class struct populated with "unknown" class Name attribute and -// empty Subclasses attribute. -func findPCIClass(info *Info, classID string) *pcidb.Class { - class := info.Classes[classID] - if class == nil { - return &pcidb.Class{ - ID: classID, - Name: util.UNKNOWN, - Subclasses: []*pcidb.Subclass{}, - } - } - return class -} - -// Returns a pointer to a pcidb.Subclass struct matching the supplied class -// and subclass ID strings. If no such subclass could be found, returns the -// pcidb.Subclass struct populated with "unknown" subclass Name attribute -// and empty ProgrammingInterfaces attribute. -func findPCISubclass( - info *Info, - classID string, - subclassID string, -) *pcidb.Subclass { - class := info.Classes[classID] - if class != nil { - for _, sc := range class.Subclasses { - if sc.ID == subclassID { - return sc - } - } - } - return &pcidb.Subclass{ - ID: subclassID, - Name: util.UNKNOWN, - ProgrammingInterfaces: []*pcidb.ProgrammingInterface{}, - } -} - -// Returns a pointer to a pcidb.ProgrammingInterface struct matching the -// supplied class, subclass and programming interface ID strings. If no such -// programming interface could be found, returns the -// pcidb.ProgrammingInterface struct populated with "unknown" Name attribute -func findPCIProgrammingInterface( - info *Info, - classID string, - subclassID string, - progIfaceID string, -) *pcidb.ProgrammingInterface { - subclass := findPCISubclass(info, classID, subclassID) - for _, pi := range subclass.ProgrammingInterfaces { - if pi.ID == progIfaceID { - return pi - } - } - return &pcidb.ProgrammingInterface{ - ID: progIfaceID, - Name: util.UNKNOWN, - } -} - -// GetDevice returns a pointer to a Device struct that describes the PCI -// device at the requested address. If no such device could be found, returns nil. -func (info *Info) GetDevice(address string) *Device { - // check cached data first - if dev := info.lookupDevice(address); dev != nil { - return dev - } - - // no cached data, let's get the information from system. - fp := getDeviceModaliasPath(info.ctx, address) - if fp == "" { - info.ctx.Warn("error finding modalias info for device %q", address) - return nil - } - - modaliasInfo := parseModaliasFile(fp) - if modaliasInfo == nil { - info.ctx.Warn("error parsing modalias info for device %q", address) - return nil - } - - device := info.getDeviceFromModaliasInfo(address, modaliasInfo) - device.Revision = getDeviceRevision(info.ctx, address) - if info.arch == topology.ARCHITECTURE_NUMA { - device.Node = getDeviceNUMANode(info.ctx, address) - } - return device -} - -// ParseDevice returns a pointer to a Device given its describing data. -// The PCI device obtained this way may not exist in the system; -// use GetDevice to get a *Device which is found in the system -func (info *Info) ParseDevice(address, modalias string) *Device { - modaliasInfo := parseModaliasData(modalias) - if modaliasInfo == nil { - return nil - } - return info.getDeviceFromModaliasInfo(address, modaliasInfo) -} - -func (info *Info) getDeviceFromModaliasInfo(address string, modaliasInfo *deviceModaliasInfo) *Device { - vendor := findPCIVendor(info, modaliasInfo.vendorID) - product := findPCIProduct( - info, - modaliasInfo.vendorID, - modaliasInfo.productID, - ) - subsystem := findPCISubsystem( - info, - modaliasInfo.vendorID, - modaliasInfo.productID, - modaliasInfo.subvendorID, - modaliasInfo.subproductID, - ) - class := findPCIClass(info, modaliasInfo.classID) - subclass := findPCISubclass( - info, - modaliasInfo.classID, - modaliasInfo.subclassID, - ) - progIface := findPCIProgrammingInterface( - info, - modaliasInfo.classID, - modaliasInfo.subclassID, - modaliasInfo.progIfaceID, - ) - - return &Device{ - Address: address, - Vendor: vendor, - Subsystem: subsystem, - Product: product, - Class: class, - Subclass: subclass, - ProgrammingInterface: progIface, - } -} - -// ListDevices returns a list of pointers to Device structs present on the -// host system -// DEPRECATED. Will be removed in v1.0. Please use -// github.com/jaypipes/pcidb to explore PCIDB information -func (info *Info) ListDevices() []*Device { - paths := linuxpath.New(info.ctx) - devs := make([]*Device, 0) - // We scan the /sys/bus/pci/devices directory which contains a collection - // of symlinks. The names of the symlinks are all the known PCI addresses - // for the host. For each address, we grab a *Device matching the - // address and append to the returned array. - links, err := ioutil.ReadDir(paths.SysBusPciDevices) - if err != nil { - info.ctx.Warn("failed to read /sys/bus/pci/devices") - return nil - } - var dev *Device - for _, link := range links { - addr := link.Name() - dev = info.GetDevice(addr) - if dev == nil { - info.ctx.Warn("failed to get device information for PCI address %s", addr) - } else { - devs = append(devs, dev) - } - } - return devs -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/pci/pci_stub.go b/vendor/github.com/jaypipes/ghw/pkg/pci/pci_stub.go deleted file mode 100644 index 2588878c44..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/pci/pci_stub.go +++ /dev/null @@ -1,30 +0,0 @@ -// +build !linux -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package pci - -import ( - "runtime" - - "github.com/pkg/errors" -) - -func (i *Info) load() error { - return errors.New("pciFillInfo not implemented on " + runtime.GOOS) -} - -// GetDevice returns a pointer to a Device struct that describes the PCI -// device at the requested address. If no such device could be found, returns -// nil -func (info *Info) GetDevice(address string) *Device { - return nil -} - -// ListDevices returns a list of pointers to Device structs present on the -// host system -func (info *Info) ListDevices() []*Device { - return nil -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/product/product.go b/vendor/github.com/jaypipes/ghw/pkg/product/product.go deleted file mode 100644 index 6a2e1ee0e5..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/product/product.go +++ /dev/null @@ -1,100 +0,0 @@ -// -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package product - -import ( - "fmt" - - "github.com/jaypipes/ghw/pkg/context" - "github.com/jaypipes/ghw/pkg/marshal" - "github.com/jaypipes/ghw/pkg/option" - "github.com/jaypipes/ghw/pkg/util" -) - -// Info defines product information -type Info struct { - ctx *context.Context - Family string `json:"family"` - Name string `json:"name"` - Vendor string `json:"vendor"` - SerialNumber string `json:"serial_number"` - UUID string `json:"uuid"` - SKU string `json:"sku"` - Version string `json:"version"` -} - -func (i *Info) String() string { - familyStr := "" - if i.Family != "" { - familyStr = " family=" + i.Family - } - nameStr := "" - if i.Name != "" { - nameStr = " name=" + i.Name - } - vendorStr := "" - if i.Vendor != "" { - vendorStr = " vendor=" + i.Vendor - } - serialStr := "" - if i.SerialNumber != "" && i.SerialNumber != util.UNKNOWN { - serialStr = " serial=" + i.SerialNumber - } - uuidStr := "" - if i.UUID != "" && i.UUID != util.UNKNOWN { - uuidStr = " uuid=" + i.UUID - } - skuStr := "" - if i.SKU != "" { - skuStr = " sku=" + i.SKU - } - versionStr := "" - if i.Version != "" { - versionStr = " version=" + i.Version - } - - res := fmt.Sprintf( - "product%s%s%s%s%s%s%s", - familyStr, - nameStr, - vendorStr, - serialStr, - uuidStr, - skuStr, - versionStr, - ) - return res -} - -// New returns a pointer to a Info struct containing information -// about the host's product -func New(opts ...*option.Option) (*Info, error) { - ctx := context.New(opts...) - info := &Info{ctx: ctx} - if err := ctx.Do(info.load); err != nil { - return nil, err - } - return info, nil -} - -// simple private struct used to encapsulate product information in a top-level -// "product" YAML/JSON map/object key -type productPrinter struct { - Info *Info `json:"product"` -} - -// YAMLString returns a string with the product information formatted as YAML -// under a top-level "dmi:" key -func (info *Info) YAMLString() string { - return marshal.SafeYAML(info.ctx, productPrinter{info}) -} - -// JSONString returns a string with the product information formatted as JSON -// under a top-level "product:" key -func (info *Info) JSONString(indent bool) string { - return marshal.SafeJSON(info.ctx, productPrinter{info}, indent) -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/product/product_linux.go b/vendor/github.com/jaypipes/ghw/pkg/product/product_linux.go deleted file mode 100644 index 36b6b4471b..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/product/product_linux.go +++ /dev/null @@ -1,23 +0,0 @@ -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package product - -import ( - "github.com/jaypipes/ghw/pkg/linuxdmi" -) - -func (i *Info) load() error { - - i.Family = linuxdmi.Item(i.ctx, "product_family") - i.Name = linuxdmi.Item(i.ctx, "product_name") - i.Vendor = linuxdmi.Item(i.ctx, "sys_vendor") - i.SerialNumber = linuxdmi.Item(i.ctx, "product_serial") - i.UUID = linuxdmi.Item(i.ctx, "product_uuid") - i.SKU = linuxdmi.Item(i.ctx, "product_sku") - i.Version = linuxdmi.Item(i.ctx, "product_version") - - return nil -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/product/product_stub.go b/vendor/github.com/jaypipes/ghw/pkg/product/product_stub.go deleted file mode 100644 index 8d848b62c2..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/product/product_stub.go +++ /dev/null @@ -1,17 +0,0 @@ -// +build !linux,!windows -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package product - -import ( - "runtime" - - "github.com/pkg/errors" -) - -func (i *Info) load() error { - return errors.New("productFillInfo not implemented on " + runtime.GOOS) -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/product/product_windows.go b/vendor/github.com/jaypipes/ghw/pkg/product/product_windows.go deleted file mode 100644 index c919cb0f6e..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/product/product_windows.go +++ /dev/null @@ -1,45 +0,0 @@ -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package product - -import ( - "github.com/StackExchange/wmi" - - "github.com/jaypipes/ghw/pkg/util" -) - -const wqlProduct = "SELECT Caption, Description, IdentifyingNumber, Name, SKUNumber, Vendor, Version, UUID FROM Win32_ComputerSystemProduct" - -type win32Product struct { - Caption *string - Description *string - IdentifyingNumber *string - Name *string - SKUNumber *string - Vendor *string - Version *string - UUID *string -} - -func (i *Info) load() error { - // Getting data from WMI - var win32ProductDescriptions []win32Product - // Assuming the first product is the host... - if err := wmi.Query(wqlProduct, &win32ProductDescriptions); err != nil { - return err - } - if len(win32ProductDescriptions) > 0 { - i.Family = util.UNKNOWN - i.Name = *win32ProductDescriptions[0].Name - i.Vendor = *win32ProductDescriptions[0].Vendor - i.SerialNumber = *win32ProductDescriptions[0].IdentifyingNumber - i.UUID = *win32ProductDescriptions[0].UUID - i.SKU = *win32ProductDescriptions[0].SKUNumber - i.Version = *win32ProductDescriptions[0].Version - } - - return nil -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/snapshot/clonetree.go b/vendor/github.com/jaypipes/ghw/pkg/snapshot/clonetree.go deleted file mode 100644 index d2f75116aa..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/snapshot/clonetree.go +++ /dev/null @@ -1,263 +0,0 @@ -// -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package snapshot - -import ( - "io/ioutil" - "os" - "path/filepath" -) - -// Attempting to tar up pseudofiles like /proc/cpuinfo is an exercise in -// futility. Notably, the pseudofiles, when read by syscalls, do not return the -// number of bytes read. This causes the tar writer to write zero-length files. -// -// Instead, it is necessary to build a directory structure in a tmpdir and -// create actual files with copies of the pseudofile contents - -// CloneTreeInto copies all the pseudofiles that ghw will consume into the root -// `scratchDir`, preserving the hieratchy. -func CloneTreeInto(scratchDir string) error { - var err error - - var createPaths = []string{ - "sys/block", - } - - for _, path := range createPaths { - if err = os.MkdirAll(filepath.Join(scratchDir, path), os.ModePerm); err != nil { - return err - } - } - - if err = createBlockDevices(scratchDir); err != nil { - return err - } - - fileSpecs := ExpectedCloneContent() - return CopyFilesInto(fileSpecs, scratchDir, nil) -} - -// ExpectedCloneContent return a slice of glob patterns which represent the pseudofiles -// ghw cares about. -// The intended usage of this function is to validate a clone tree, checking that the -// content matches the expectations. -// Beware: the content is host-specific, because the content pertaining some subsystems, -// most notably PCI, is host-specific and unpredictable. -func ExpectedCloneContent() []string { - fileSpecs := ExpectedCloneStaticContent() - fileSpecs = append(fileSpecs, ExpectedCloneNetContent()...) - fileSpecs = append(fileSpecs, ExpectedClonePCIContent()...) - fileSpecs = append(fileSpecs, ExpectedCloneGPUContent()...) - return fileSpecs -} - -// ExpectedCloneStaticContent return a slice of glob patterns which represent the pseudofiles -// ghw cares about, and which are independent from host specific topology or configuration, -// thus are safely represented by a static slice - e.g. they don't need to be discovered at runtime. -func ExpectedCloneStaticContent() []string { - return []string{ - "/etc/mtab", - "/proc/cpuinfo", - "/proc/meminfo", - "/sys/devices/system/cpu/cpu*/cache/index*/*", - "/sys/devices/system/cpu/cpu*/topology/*", - "/sys/devices/system/memory/block_size_bytes", - "/sys/devices/system/memory/memory*/online", - "/sys/devices/system/memory/memory*/state", - "/sys/devices/system/node/has_*", - "/sys/devices/system/node/online", - "/sys/devices/system/node/possible", - "/sys/devices/system/node/node*/cpu*", - "/sys/devices/system/node/node*/distance", - } -} - -// ValidateClonedTree checks the content of a cloned tree, whose root is `clonedDir`, -// against a slice of glob specs which must be included in the cloned tree. -// Is not wrong, and this functions doesn't enforce this, that the cloned tree includes -// more files than the necessary; ghw will just ignore the files it doesn't care about. -// Returns a slice of glob patters expected (given) but not found in the cloned tree, -// and the error during the validation (if any). -func ValidateClonedTree(fileSpecs []string, clonedDir string) ([]string, error) { - missing := []string{} - for _, fileSpec := range fileSpecs { - matches, err := filepath.Glob(filepath.Join(clonedDir, fileSpec)) - if err != nil { - return missing, err - } - if len(matches) == 0 { - missing = append(missing, fileSpec) - } - } - return missing, nil -} - -func copyPseudoFile(path, targetPath string) error { - buf, err := ioutil.ReadFile(path) - if err != nil { - return err - } - trace("creating %s\n", targetPath) - f, err := os.Create(targetPath) - if err != nil { - return err - } - if _, err = f.Write(buf); err != nil { - return err - } - f.Close() - return nil -} - -// CopyFileOptions allows to finetune the behaviour of the CopyFilesInto function -type CopyFileOptions struct { - // IsSymlinkFn allows to control the behaviour when handling a symlink. - // If this hook returns true, the source file is treated as symlink: the cloned - // tree will thus contain a symlink, with its path adjusted to match the relative - // path inside the cloned tree. If return false, the symlink will be deferred. - // The easiest use case of this hook is if you want to avoid symlinks in your cloned - // tree (having duplicated content). In this case you can just add a function - // which always return false. - IsSymlinkFn func(path string, info os.FileInfo) bool -} - -// CopyFilesInto copies all the given glob files specs in the given `destDir` directory, -// preserving the directory structure. This means you can provide a deeply nested filespec -// like -// - /some/deeply/nested/file* -// and you DO NOT need to build the tree incrementally like -// - /some/ -// - /some/deeply/ -// ... -// all glob patterns supported in `filepath.Glob` are supported. -func CopyFilesInto(fileSpecs []string, destDir string, opts *CopyFileOptions) error { - if opts == nil { - opts = &CopyFileOptions{ - IsSymlinkFn: isSymlink, - } - } - for _, fileSpec := range fileSpecs { - trace("copying spec: %q\n", fileSpec) - matches, err := filepath.Glob(fileSpec) - if err != nil { - return err - } - if err := copyFileTreeInto(matches, destDir, opts); err != nil { - return err - } - } - return nil -} - -func copyFileTreeInto(paths []string, destDir string, opts *CopyFileOptions) error { - for _, path := range paths { - trace(" copying path: %q\n", path) - baseDir := filepath.Dir(path) - if err := os.MkdirAll(filepath.Join(destDir, baseDir), os.ModePerm); err != nil { - return err - } - - fi, err := os.Lstat(path) - if err != nil { - return err - } - // directories must be listed explicitely and created separately. - // In the future we may want to expose this decision as hook point in - // CopyFileOptions, when clear use cases emerge. - if fi.IsDir() { - trace("expanded glob path %q is a directory - skipped", path) - continue - } - if opts.IsSymlinkFn(path, fi) { - trace(" copying link: %q\n", path) - if err := copyLink(path, filepath.Join(destDir, path)); err != nil { - return err - } - } else { - trace(" copying file: %q\n", path) - if err := copyPseudoFile(path, filepath.Join(destDir, path)); err != nil { - return err - } - } - } - return nil -} - -func isSymlink(path string, fi os.FileInfo) bool { - return fi.Mode()&os.ModeSymlink != 0 -} - -func copyLink(path, targetPath string) error { - target, err := os.Readlink(path) - if err != nil { - return err - } - if err := os.Symlink(target, targetPath); err != nil { - return err - } - - return nil -} - -type filterFunc func(string) bool - -// cloneContentByClass copies all the content related to a given device class -// (devClass), possibly filtering out devices whose name does NOT pass a -// filter (filterName). Each entry in `/sys/class/$CLASS` is actually a -// symbolic link. We can filter out entries depending on the link target. -// Each filter is a simple function which takes the entry name or the link -// target and must return true if the entry should be collected, false -// otherwise. Last, explicitely collect a list of attributes for each entry, -// given as list of glob patterns as `subEntries`. -// Return the final list of glob patterns to be collected. -func cloneContentByClass(devClass string, subEntries []string, filterName filterFunc, filterLink filterFunc) []string { - var fileSpecs []string - - // warning: don't use the context package here, this means not even the linuxpath package. - // TODO(fromani) remove the path duplication - sysClass := filepath.Join("sys", "class", devClass) - entries, err := ioutil.ReadDir(sysClass) - if err != nil { - // we should not import context, hence we can't Warn() - return fileSpecs - } - for _, entry := range entries { - devName := entry.Name() - - if !filterName(devName) { - continue - } - - devPath := filepath.Join(sysClass, devName) - dest, err := os.Readlink(devPath) - if err != nil { - continue - } - - if !filterLink(dest) { - continue - } - - // so, first copy the symlink itself - fileSpecs = append(fileSpecs, devPath) - // now we have to clone the content of the actual entry - // related (and found into a subdir of) the backing hardware - // device - devData := filepath.Clean(filepath.Join(sysClass, dest)) - for _, subEntry := range subEntries { - fileSpecs = append(fileSpecs, filepath.Join(devData, subEntry)) - } - } - - return fileSpecs -} - -// filterNone allows all content, filtering out none of it -func filterNone(_ string) bool { - return true -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/snapshot/clonetree_block.go b/vendor/github.com/jaypipes/ghw/pkg/snapshot/clonetree_block.go deleted file mode 100644 index 18e2161a4e..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/snapshot/clonetree_block.go +++ /dev/null @@ -1,221 +0,0 @@ -// -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package snapshot - -import ( - "errors" - "io/ioutil" - "os" - "path/filepath" - "strings" -) - -func createBlockDevices(buildDir string) error { - // Grab all the block device pseudo-directories from /sys/block symlinks - // (excluding loopback devices) and inject them into our build filesystem - // with all but the circular symlink'd subsystem directories - devLinks, err := ioutil.ReadDir("/sys/block") - if err != nil { - return err - } - for _, devLink := range devLinks { - dname := devLink.Name() - if strings.HasPrefix(dname, "loop") { - continue - } - devPath := filepath.Join("/sys/block", dname) - trace("processing block device %q\n", devPath) - - // from the sysfs layout, we know this is always a symlink - linkContentPath, err := os.Readlink(devPath) - if err != nil { - return err - } - trace("link target for block device %q is %q\n", devPath, linkContentPath) - - // Create a symlink in our build filesystem that is a directory - // pointing to the actual device bus path where the block device's - // information directory resides - linkPath := filepath.Join(buildDir, "sys/block", dname) - linkTargetPath := filepath.Join( - buildDir, - "sys/block", - strings.TrimPrefix(linkContentPath, string(os.PathSeparator)), - ) - trace("creating device directory %s\n", linkTargetPath) - if err = os.MkdirAll(linkTargetPath, os.ModePerm); err != nil { - return err - } - - trace("linking device directory %s to %s\n", linkPath, linkContentPath) - // Make sure the link target is a relative path! - // if we use absolute path, the link target will be an absolute path starting - // with buildDir, hence the snapshot will contain broken link. - // Otherwise, the unpack directory will never have the same prefix of buildDir! - if err = os.Symlink(linkContentPath, linkPath); err != nil { - return err - } - // Now read the source block device directory and populate the - // newly-created target link in the build directory with the - // appropriate block device pseudofiles - srcDeviceDir := filepath.Join( - "/sys/block", - strings.TrimPrefix(linkContentPath, string(os.PathSeparator)), - ) - trace("creating device directory %q from %q\n", linkTargetPath, srcDeviceDir) - if err = createBlockDeviceDir(linkTargetPath, srcDeviceDir); err != nil { - return err - } - } - return nil -} - -func createBlockDeviceDir(buildDeviceDir string, srcDeviceDir string) error { - // Populate the supplied directory (in our build filesystem) with all the - // appropriate information pseudofile contents for the block device. - devName := filepath.Base(srcDeviceDir) - devFiles, err := ioutil.ReadDir(srcDeviceDir) - if err != nil { - return err - } - for _, f := range devFiles { - fname := f.Name() - fp := filepath.Join(srcDeviceDir, fname) - fi, err := os.Lstat(fp) - if err != nil { - return err - } - if fi.Mode()&os.ModeSymlink != 0 { - // Ignore any symlinks in the deviceDir since they simply point to - // either self-referential links or information we aren't - // interested in like "subsystem" - continue - } else if fi.IsDir() { - if strings.HasPrefix(fname, devName) { - // We're interested in are the directories that begin with the - // block device name. These are directories with information - // about the partitions on the device - buildPartitionDir := filepath.Join( - buildDeviceDir, fname, - ) - srcPartitionDir := filepath.Join( - srcDeviceDir, fname, - ) - trace("creating partition directory %s\n", buildPartitionDir) - err = os.MkdirAll(buildPartitionDir, os.ModePerm) - if err != nil { - return err - } - err = createPartitionDir(buildPartitionDir, srcPartitionDir) - if err != nil { - return err - } - } - } else if fi.Mode().IsRegular() { - // Regular files in the block device directory are both regular and - // pseudofiles containing information such as the size (in sectors) - // and whether the device is read-only - buf, err := ioutil.ReadFile(fp) - if err != nil { - if errors.Is(err, os.ErrPermission) { - // example: /sys/devices/virtual/block/zram0/compact is 0400 - trace("permission denied reading %q - skipped\n", fp) - continue - } - return err - } - targetPath := filepath.Join(buildDeviceDir, fname) - trace("creating %s\n", targetPath) - f, err := os.Create(targetPath) - if err != nil { - return err - } - if _, err = f.Write(buf); err != nil { - return err - } - f.Close() - } - } - // There is a special file $DEVICE_DIR/queue/rotational that, for some hard - // drives, contains a 1 or 0 indicating whether the device is a spinning - // disk or not - srcQueueDir := filepath.Join( - srcDeviceDir, - "queue", - ) - buildQueueDir := filepath.Join( - buildDeviceDir, - "queue", - ) - err = os.MkdirAll(buildQueueDir, os.ModePerm) - if err != nil { - return err - } - fp := filepath.Join(srcQueueDir, "rotational") - buf, err := ioutil.ReadFile(fp) - if err != nil { - return err - } - targetPath := filepath.Join(buildQueueDir, "rotational") - trace("creating %s\n", targetPath) - f, err := os.Create(targetPath) - if err != nil { - return err - } - if _, err = f.Write(buf); err != nil { - return err - } - f.Close() - - return nil -} - -func createPartitionDir(buildPartitionDir string, srcPartitionDir string) error { - // Populate the supplied directory (in our build filesystem) with all the - // appropriate information pseudofile contents for the partition. - partFiles, err := ioutil.ReadDir(srcPartitionDir) - if err != nil { - return err - } - for _, f := range partFiles { - fname := f.Name() - fp := filepath.Join(srcPartitionDir, fname) - fi, err := os.Lstat(fp) - if err != nil { - return err - } - if fi.Mode()&os.ModeSymlink != 0 { - // Ignore any symlinks in the partition directory since they simply - // point to information we aren't interested in like "subsystem" - continue - } else if fi.IsDir() { - // The subdirectories in the partition directory are not - // interesting for us. They have information about power events and - // traces - continue - } else if fi.Mode().IsRegular() { - // Regular files in the block device directory are both regular and - // pseudofiles containing information such as the size (in sectors) - // and whether the device is read-only - buf, err := ioutil.ReadFile(fp) - if err != nil { - return err - } - targetPath := filepath.Join(buildPartitionDir, fname) - trace("creating %s\n", targetPath) - f, err := os.Create(targetPath) - if err != nil { - return err - } - if _, err = f.Write(buf); err != nil { - return err - } - f.Close() - } - } - return nil -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/snapshot/clonetree_gpu.go b/vendor/github.com/jaypipes/ghw/pkg/snapshot/clonetree_gpu.go deleted file mode 100644 index a26d6b01fb..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/snapshot/clonetree_gpu.go +++ /dev/null @@ -1,33 +0,0 @@ -// -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package snapshot - -import ( - "strings" -) - -// ExpectedCloneGPUContent returns a slice of strings pertaining to the GPU devices ghw -// cares about. We cannot use a static list because we want to grab only the first cardX data -// (see comment in pkg/gpu/gpu_linux.go) -// Additionally, we want to make sure to clone the backing device data. -func ExpectedCloneGPUContent() []string { - cardEntries := []string{ - "device", - } - - filterName := func(cardName string) bool { - if !strings.HasPrefix(cardName, "card") { - return false - } - if strings.ContainsRune(cardName, '-') { - return false - } - return true - } - - return cloneContentByClass("drm", cardEntries, filterName, filterNone) -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/snapshot/clonetree_net.go b/vendor/github.com/jaypipes/ghw/pkg/snapshot/clonetree_net.go deleted file mode 100644 index 6c89a6cc39..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/snapshot/clonetree_net.go +++ /dev/null @@ -1,31 +0,0 @@ -// -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package snapshot - -import ( - "strings" -) - -// ExpectedCloneNetContent returns a slice of strings pertaning to the network interfaces ghw -// cares about. We cannot use a static list because we want to filter away the virtual devices, -// which ghw doesn't concern itself about. So we need to do some runtime discovery. -// Additionally, we want to make sure to clone the backing device data. -func ExpectedCloneNetContent() []string { - ifaceEntries := []string{ - "addr_assign_type", - // intentionally avoid to clone "address" to avoid to leak any host-idenfifiable data. - } - - filterLink := func(linkDest string) bool { - if strings.Contains(linkDest, "devices/virtual/net") { - return false - } - return true - } - - return cloneContentByClass("net", ifaceEntries, filterNone, filterLink) -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/snapshot/clonetree_pci.go b/vendor/github.com/jaypipes/ghw/pkg/snapshot/clonetree_pci.go deleted file mode 100644 index 503a562d9c..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/snapshot/clonetree_pci.go +++ /dev/null @@ -1,148 +0,0 @@ -// -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package snapshot - -import ( - "fmt" - "io/ioutil" - "os" - "path/filepath" - - pciaddr "github.com/jaypipes/ghw/pkg/pci/address" -) - -const ( - // root directory: entry point to start scanning the PCI forest - // warning: don't use the context package here, this means not even the linuxpath package. - // TODO(fromani) remove the path duplication - sysBusPCIDir = "/sys/bus/pci/devices" -) - -// ExpectedClonePCIContent return a slice of glob patterns which represent the pseudofiles -// ghw cares about, pertaining to PCI devices only. -// Beware: the content is host-specific, because the PCI topology is host-dependent and unpredictable. -func ExpectedClonePCIContent() []string { - var fileSpecs []string - pciRoots := []string{ - sysBusPCIDir, - } - for { - if len(pciRoots) == 0 { - break - } - pciRoot := pciRoots[0] - pciRoots = pciRoots[1:] - specs, roots := scanPCIDeviceRoot(pciRoot) - pciRoots = append(pciRoots, roots...) - fileSpecs = append(fileSpecs, specs...) - } - return fileSpecs -} - -// scanPCIDeviceRoot reports a slice of glob patterns which represent the pseudofiles -// ghw cares about pertaining to all the PCI devices connected to the bus connected from the -// given root; usually (but not always) a CPU packages has 1+ PCI(e) roots, forming the first -// level; more PCI bridges are (usually) attached to this level, creating deep nested trees. -// hence we need to scan all possible roots, to make sure not to miss important devices. -// -// note about notifying errors. This function and its helper functions do use trace() everywhere -// to report recoverable errors, even though it would have been appropriate to use Warn(). -// This is unfortunate, and again a byproduct of the fact we cannot use context.Context to avoid -// circular dependencies. -// TODO(fromani): switch to Warn() as soon as we figure out how to break this circular dep. -func scanPCIDeviceRoot(root string) (fileSpecs []string, pciRoots []string) { - trace("scanning PCI device root %q\n", root) - - perDevEntries := []string{ - "class", - "device", - "irq", - "local_cpulist", - "modalias", - "numa_node", - "revision", - "vendor", - } - entries, err := ioutil.ReadDir(root) - if err != nil { - return []string{}, []string{} - } - for _, entry := range entries { - entryName := entry.Name() - if addr := pciaddr.FromString(entryName); addr == nil { - // doesn't look like a entry we care about - // This is by far and large the most likely path - // hence we should NOT trace/warn here. - continue - } - - entryPath := filepath.Join(root, entryName) - pciEntry, err := findPCIEntryFromPath(root, entryName) - if err != nil { - trace("error scanning %q: %v", entryName, err) - continue - } - - trace("PCI entry is %q\n", pciEntry) - fileSpecs = append(fileSpecs, entryPath) - for _, perNetEntry := range perDevEntries { - fileSpecs = append(fileSpecs, filepath.Join(pciEntry, perNetEntry)) - } - - if isPCIBridge(entryPath) { - trace("adding new PCI root %q\n", entryName) - pciRoots = append(pciRoots, pciEntry) - } - } - return fileSpecs, pciRoots -} - -func findPCIEntryFromPath(root, entryName string) (string, error) { - entryPath := filepath.Join(root, entryName) - fi, err := os.Lstat(entryPath) - if err != nil { - return "", fmt.Errorf("stat(%s) failed: %v\n", entryPath, err) - } - if fi.Mode()&os.ModeSymlink == 0 { - // regular file, nothing to resolve - return entryPath, nil - } - // resolve symlink - target, err := os.Readlink(entryPath) - trace("entry %q is symlink resolved to %q\n", entryPath, target) - if err != nil { - return "", fmt.Errorf("readlink(%s) failed: %v - skipped\n", entryPath, err) - } - return filepath.Clean(filepath.Join(root, target)), nil -} - -func isPCIBridge(entryPath string) bool { - subNodes, err := ioutil.ReadDir(entryPath) - if err != nil { - // this is so unlikely we don't even return error. But we trace just in case. - trace("error scanning device entry path %q: %v", entryPath, err) - return false - } - for _, subNode := range subNodes { - if !subNode.IsDir() { - continue - } - if addr := pciaddr.FromString(subNode.Name()); addr != nil { - // we got an entry in the directory pertaining to this device - // which is a directory itself and it is named like a PCI address. - // Hence we infer the device we are considering is a PCI bridge of sorts. - // This is is indeed a bit brutal, but the only possible alternative - // (besides blindly copying everything in /sys/bus/pci/devices) is - // to detect the type of the device and pick only the bridges. - // This approach duplicates the logic within the `pci` subkpg - // - or forces us into awkward dep cycles, and has poorer forward - // compatibility. - return true - } - } - return false -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/snapshot/pack.go b/vendor/github.com/jaypipes/ghw/pkg/snapshot/pack.go deleted file mode 100644 index 8d9bd95914..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/snapshot/pack.go +++ /dev/null @@ -1,112 +0,0 @@ -// -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package snapshot - -import ( - "archive/tar" - "compress/gzip" - "errors" - "fmt" - "io" - "os" - "path/filepath" - "strings" -) - -// PackFrom creates the snapshot named `snapshotName` from the -// directory tree whose root is `sourceRoot`. -func PackFrom(snapshotName, sourceRoot string) error { - f, err := OpenDestination(snapshotName) - if err != nil { - return err - } - defer f.Close() - - return PackWithWriter(f, sourceRoot) -} - -// OpenDestination opens the `snapshotName` file for writing, bailing out -// if the file seems to exist and have existing content already. -// This is done to avoid accidental overwrites. -func OpenDestination(snapshotName string) (*os.File, error) { - var f *os.File - var err error - - if _, err = os.Stat(snapshotName); errors.Is(err, os.ErrNotExist) { - if f, err = os.Create(snapshotName); err != nil { - return nil, err - } - } else if err != nil { - return nil, err - } else { - f, err := os.OpenFile(snapshotName, os.O_WRONLY, 0600) - if err != nil { - return nil, err - } - fs, err := f.Stat() - if err != nil { - return nil, err - } - if fs.Size() > 0 { - return nil, fmt.Errorf("File %s already exists and is of size >0", snapshotName) - } - } - return f, nil -} - -// PakcWithWriter creates a snapshot sending all the binary data to the -// given `fw` writer. The snapshot is made from the directory tree whose -// root is `sourceRoot`. -func PackWithWriter(fw io.Writer, sourceRoot string) error { - gzw := gzip.NewWriter(fw) - defer gzw.Close() - - tw := tar.NewWriter(gzw) - defer tw.Close() - - return createSnapshot(tw, sourceRoot) -} - -func createSnapshot(tw *tar.Writer, buildDir string) error { - return filepath.Walk(buildDir, func(path string, fi os.FileInfo, err error) error { - if path == buildDir { - return nil - } - var link string - - if fi.Mode()&os.ModeSymlink != 0 { - trace("processing symlink %s\n", path) - link, err = os.Readlink(path) - if err != nil { - return err - } - } - - hdr, err := tar.FileInfoHeader(fi, link) - if err != nil { - return err - } - hdr.Name = strings.TrimPrefix(strings.TrimPrefix(path, buildDir), string(os.PathSeparator)) - - if err = tw.WriteHeader(hdr); err != nil { - return err - } - - switch hdr.Typeflag { - case tar.TypeReg, tar.TypeRegA: - f, err := os.Open(path) - if err != nil { - return err - } - if _, err = io.Copy(tw, f); err != nil { - return err - } - f.Close() - } - return nil - }) -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/snapshot/testdata.tar.gz b/vendor/github.com/jaypipes/ghw/pkg/snapshot/testdata.tar.gz deleted file mode 100644 index edb26fbda3..0000000000 Binary files a/vendor/github.com/jaypipes/ghw/pkg/snapshot/testdata.tar.gz and /dev/null differ diff --git a/vendor/github.com/jaypipes/ghw/pkg/snapshot/trace.go b/vendor/github.com/jaypipes/ghw/pkg/snapshot/trace.go deleted file mode 100644 index ad8086bd5e..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/snapshot/trace.go +++ /dev/null @@ -1,19 +0,0 @@ -// -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package snapshot - -var trace func(msg string, args ...interface{}) - -func init() { - trace = func(msg string, args ...interface{}) { - return - } -} - -func SetTraceFunction(fn func(msg string, args ...interface{})) { - trace = fn -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/snapshot/unpack.go b/vendor/github.com/jaypipes/ghw/pkg/snapshot/unpack.go deleted file mode 100644 index 3df395e277..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/snapshot/unpack.go +++ /dev/null @@ -1,129 +0,0 @@ -// -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package snapshot - -import ( - "archive/tar" - "compress/gzip" - "io" - "io/ioutil" - "os" - "path/filepath" - - "github.com/jaypipes/ghw/pkg/option" -) - -const ( - TargetRoot = "ghw-snapshot-*" -) - -const ( - // If set, `ghw` will not unpack the snapshot in the user-supplied directory - // unless the aforementioned directory is empty. - OwnTargetDirectory = 1 << iota -) - -// Clanup removes the unpacket snapshot from the target root. -// Please not that the environs variable `GHW_SNAPSHOT_PRESERVE`, if set, -// will make this function silently skip. -func Cleanup(targetRoot string) error { - if option.EnvOrDefaultSnapshotPreserve() { - return nil - } - return os.RemoveAll(targetRoot) -} - -// Unpack expands the given snapshot in a temporary directory managed by `ghw`. Returns the path of that directory. -func Unpack(snapshotName string) (string, error) { - targetRoot, err := ioutil.TempDir("", TargetRoot) - if err != nil { - return "", err - } - _, err = UnpackInto(snapshotName, targetRoot, 0) - return targetRoot, err -} - -// UnpackInto expands the given snapshot in a client-supplied directory. -// Returns true if the snapshot was actually unpacked, false otherwise -func UnpackInto(snapshotName, targetRoot string, flags uint) (bool, error) { - if (flags&OwnTargetDirectory) == OwnTargetDirectory && !isEmptyDir(targetRoot) { - return false, nil - } - snap, err := os.Open(snapshotName) - if err != nil { - return false, err - } - defer snap.Close() - return true, Untar(targetRoot, snap) -} - -// Untar extracts data from the given reader (providing data in tar.gz format) and unpacks it in the given directory. -func Untar(root string, r io.Reader) error { - var err error - gzr, err := gzip.NewReader(r) - if err != nil { - return err - } - defer gzr.Close() - - tr := tar.NewReader(gzr) - for { - header, err := tr.Next() - if err == io.EOF { - // we are done - return nil - } - - if err != nil { - // bail out - return err - } - - if header == nil { - // TODO: how come? - continue - } - - target := filepath.Join(root, header.Name) - mode := os.FileMode(header.Mode) - - switch header.Typeflag { - case tar.TypeDir: - err = os.MkdirAll(target, mode) - if err != nil { - return err - } - - case tar.TypeReg: - dst, err := os.OpenFile(target, os.O_CREATE|os.O_RDWR, mode) - if err != nil { - return err - } - - _, err = io.Copy(dst, tr) - if err != nil { - return err - } - - dst.Close() - - case tar.TypeSymlink: - err = os.Symlink(header.Linkname, target) - if err != nil { - return err - } - } - } -} - -func isEmptyDir(name string) bool { - entries, err := ioutil.ReadDir(name) - if err != nil { - return false - } - return len(entries) == 0 -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/topology/topology.go b/vendor/github.com/jaypipes/ghw/pkg/topology/topology.go deleted file mode 100644 index a846584dcb..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/topology/topology.go +++ /dev/null @@ -1,128 +0,0 @@ -// -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package topology - -import ( - "fmt" - "sort" - "strings" - - "github.com/jaypipes/ghw/pkg/context" - "github.com/jaypipes/ghw/pkg/cpu" - "github.com/jaypipes/ghw/pkg/marshal" - "github.com/jaypipes/ghw/pkg/memory" - "github.com/jaypipes/ghw/pkg/option" -) - -// Architecture describes the overall hardware architecture. It can be either -// Symmetric Multi-Processor (SMP) or Non-Uniform Memory Access (NUMA) -type Architecture int - -const ( - // SMP is a Symmetric Multi-Processor system - ARCHITECTURE_SMP Architecture = iota - // NUMA is a Non-Uniform Memory Access system - ARCHITECTURE_NUMA -) - -var ( - architectureString = map[Architecture]string{ - ARCHITECTURE_SMP: "SMP", - ARCHITECTURE_NUMA: "NUMA", - } -) - -func (a Architecture) String() string { - return architectureString[a] -} - -// NOTE(jaypipes): since serialized output is as "official" as we're going to -// get, let's lowercase the string output when serializing, in order to -// "normalize" the expected serialized output -func (a Architecture) MarshalJSON() ([]byte, error) { - return []byte("\"" + strings.ToLower(a.String()) + "\""), nil -} - -// Node is an abstract construct representing a collection of processors and -// various levels of memory cache that those processors share. In a NUMA -// architecture, there are multiple NUMA nodes, abstracted here as multiple -// Node structs. In an SMP architecture, a single Node will be available in the -// Info struct and this single struct can be used to describe the levels of -// memory caching available to the single physical processor package's physical -// processor cores -type Node struct { - ID int `json:"id"` - Cores []*cpu.ProcessorCore `json:"cores"` - Caches []*memory.Cache `json:"caches"` - Distances []int `json:"distances"` -} - -func (n *Node) String() string { - return fmt.Sprintf( - "node #%d (%d cores)", - n.ID, - len(n.Cores), - ) -} - -// Info describes the system topology for the host hardware -type Info struct { - ctx *context.Context - Architecture Architecture `json:"architecture"` - Nodes []*Node `json:"nodes"` -} - -// New returns a pointer to an Info struct that contains information about the -// NUMA topology on the host system -func New(opts ...*option.Option) (*Info, error) { - return NewWithContext(context.New(opts...)) -} - -// NewWithContext returns a pointer to an Info struct that contains information about -// the NUMA topology on the host system. Use this function when you want to consume -// the topology package from another package (e.g. pci, gpu) -func NewWithContext(ctx *context.Context) (*Info, error) { - info := &Info{ctx: ctx} - if err := ctx.Do(info.load); err != nil { - return nil, err - } - for _, node := range info.Nodes { - sort.Sort(memory.SortByCacheLevelTypeFirstProcessor(node.Caches)) - } - return info, nil -} - -func (i *Info) String() string { - archStr := "SMP" - if i.Architecture == ARCHITECTURE_NUMA { - archStr = "NUMA" - } - res := fmt.Sprintf( - "topology %s (%d nodes)", - archStr, - len(i.Nodes), - ) - return res -} - -// simple private struct used to encapsulate topology information in a -// top-level "topology" YAML/JSON map/object key -type topologyPrinter struct { - Info *Info `json:"topology"` -} - -// YAMLString returns a string with the topology information formatted as YAML -// under a top-level "topology:" key -func (i *Info) YAMLString() string { - return marshal.SafeYAML(i.ctx, topologyPrinter{i}) -} - -// JSONString returns a string with the topology information formatted as JSON -// under a top-level "topology:" key -func (i *Info) JSONString(indent bool) string { - return marshal.SafeJSON(i.ctx, topologyPrinter{i}, indent) -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/topology/topology_linux.go b/vendor/github.com/jaypipes/ghw/pkg/topology/topology_linux.go deleted file mode 100644 index 4c3bbb16b7..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/topology/topology_linux.go +++ /dev/null @@ -1,100 +0,0 @@ -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package topology - -import ( - "fmt" - "io/ioutil" - "path/filepath" - "strconv" - "strings" - - "github.com/jaypipes/ghw/pkg/context" - "github.com/jaypipes/ghw/pkg/cpu" - "github.com/jaypipes/ghw/pkg/linuxpath" - "github.com/jaypipes/ghw/pkg/memory" -) - -func (i *Info) load() error { - i.Nodes = topologyNodes(i.ctx) - if len(i.Nodes) == 1 { - i.Architecture = ARCHITECTURE_SMP - } else { - i.Architecture = ARCHITECTURE_NUMA - } - return nil -} - -func topologyNodes(ctx *context.Context) []*Node { - paths := linuxpath.New(ctx) - nodes := make([]*Node, 0) - - files, err := ioutil.ReadDir(paths.SysDevicesSystemNode) - if err != nil { - ctx.Warn("failed to determine nodes: %s\n", err) - return nodes - } - for _, file := range files { - filename := file.Name() - if !strings.HasPrefix(filename, "node") { - continue - } - node := &Node{} - nodeID, err := strconv.Atoi(filename[4:]) - if err != nil { - ctx.Warn("failed to determine node ID: %s\n", err) - return nodes - } - node.ID = nodeID - cores, err := cpu.CoresForNode(ctx, nodeID) - if err != nil { - ctx.Warn("failed to determine cores for node: %s\n", err) - return nodes - } - node.Cores = cores - caches, err := memory.CachesForNode(ctx, nodeID) - if err != nil { - ctx.Warn("failed to determine caches for node: %s\n", err) - return nodes - } - node.Caches = caches - - distances, err := distancesForNode(ctx, nodeID) - if err != nil { - ctx.Warn("failed to determine node distances for node: %s\n", err) - return nodes - } - node.Distances = distances - - nodes = append(nodes, node) - } - return nodes -} - -func distancesForNode(ctx *context.Context, nodeID int) ([]int, error) { - paths := linuxpath.New(ctx) - path := filepath.Join( - paths.SysDevicesSystemNode, - fmt.Sprintf("node%d", nodeID), - "distance", - ) - - data, err := ioutil.ReadFile(path) - if err != nil { - return nil, err - } - - items := strings.Fields(strings.TrimSpace(string(data))) - dists := make([]int, len(items), len(items)) // TODO: can a NUMA cell be offlined? - for idx, item := range items { - dist, err := strconv.Atoi(item) - if err != nil { - return dists, err - } - dists[idx] = dist - } - return dists, nil -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/topology/topology_stub.go b/vendor/github.com/jaypipes/ghw/pkg/topology/topology_stub.go deleted file mode 100644 index b2b801f7bf..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/topology/topology_stub.go +++ /dev/null @@ -1,17 +0,0 @@ -// +build !linux,!windows -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package topology - -import ( - "runtime" - - "github.com/pkg/errors" -) - -func (i *Info) load() error { - return errors.New("topologyFillInfo not implemented on " + runtime.GOOS) -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/topology/topology_windows.go b/vendor/github.com/jaypipes/ghw/pkg/topology/topology_windows.go deleted file mode 100644 index 3141ac99c9..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/topology/topology_windows.go +++ /dev/null @@ -1,156 +0,0 @@ -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package topology - -import ( - "encoding/binary" - "fmt" - "syscall" - "unsafe" -) - -const ( - rcFailure = 0 - sizeofLogicalProcessorInfo = 32 - errInsufficientBuffer syscall.Errno = 122 - - relationProcessorCore = 0 - relationNUMANode = 1 - relationCache = 2 - relationProcessorPackage = 3 - relationGroup = 4 -) - -func (i *Info) load() error { - nodes, err := topologyNodes() - if err != nil { - return err - } - i.Nodes = nodes - if len(nodes) == 1 { - i.Architecture = ARCHITECTURE_SMP - } else { - i.Architecture = ARCHITECTURE_NUMA - } - return nil -} - -func topologyNodes() ([]*Node, error) { - nodes := make([]*Node, 0) - lpis, err := getWin32LogicalProcessorInfos() - if err != nil { - return nil, err - } - for _, lpi := range lpis { - switch lpi.relationship { - case relationNUMANode: - nodes = append(nodes, &Node{ - ID: lpi.numaNodeID(), - }) - case relationProcessorCore: - // TODO(jaypipes): associated LP to processor core - case relationProcessorPackage: - // ignore - case relationCache: - // TODO(jaypipes) handle cache layers - default: - return nil, fmt.Errorf("Unknown LOGICAL_PROCESSOR_RELATIONSHIP value: %d", lpi.relationship) - - } - } - return nodes, nil -} - -// This is the CACHE_DESCRIPTOR struct in the Win32 API -type cacheDescriptor struct { - level uint8 - associativity uint8 - lineSize uint16 - size uint32 - cacheType uint32 -} - -// This is the SYSTEM_LOGICAL_PROCESSOR_INFORMATION struct in the Win32 API -type logicalProcessorInfo struct { - processorMask uint64 - relationship uint64 - // The following dummyunion member is a representation of this part of - // the SYSTEM_LOGICAL_PROCESSOR_INFORMATION struct: - // - // union { - // struct { - // BYTE Flags; - // } ProcessorCore; - // struct { - // DWORD NodeNumber; - // } NumaNode; - // CACHE_DESCRIPTOR Cache; - // ULONGLONG Reserved[2]; - // } DUMMYUNIONNAME; - dummyunion [16]byte -} - -// numaNodeID returns the NUMA node's identifier from the logical processor -// information struct by grabbing the integer representation of the struct's -// NumaNode unioned data element -func (lpi *logicalProcessorInfo) numaNodeID() int { - if lpi.relationship != relationNUMANode { - return -1 - } - return int(binary.LittleEndian.Uint16(lpi.dummyunion[0:])) -} - -// ref: https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getlogicalprocessorinformation -func getWin32LogicalProcessorInfos() ( - []*logicalProcessorInfo, - error, -) { - lpis := make([]*logicalProcessorInfo, 0) - win32api := syscall.NewLazyDLL("kernel32.dll") - glpi := win32api.NewProc("GetLogicalProcessorInformation") - - // The way the GetLogicalProcessorInformation (GLPI) Win32 API call - // works is wonky, but consistent with the Win32 API calling structure. - // Basically, you need to first call the GLPI API with a NUL pointerr - // and a pointer to an integer. That first call to the API should - // return ERROR_INSUFFICIENT_BUFFER, which is the indication that the - // supplied buffer pointer is NUL and needs to have memory allocated to - // it of an amount equal to the value of the integer pointer argument. - // Once the buffer is allocated this amount of space, the GLPI API call - // is again called. This time, the return value should be 0 and the - // buffer will have been set to an array of - // SYSTEM_LOGICAL_PROCESSOR_INFORMATION structs. - toAllocate := uint32(0) - // first, figure out how much we need - rc, _, win32err := glpi.Call(uintptr(0), uintptr(unsafe.Pointer(&toAllocate))) - if rc == rcFailure { - if win32err != errInsufficientBuffer { - return nil, fmt.Errorf("GetLogicalProcessorInformation Win32 API initial call failed to return ERROR_INSUFFICIENT_BUFFER") - } - } else { - // This shouldn't happen because buffer hasn't yet been allocated... - return nil, fmt.Errorf("GetLogicalProcessorInformation Win32 API initial call returned success instead of failure with ERROR_INSUFFICIENT_BUFFER") - } - - // OK, now we actually allocate a raw buffer to fill with some number - // of SYSTEM_LOGICAL_PROCESSOR_INFORMATION structs - b := make([]byte, toAllocate) - rc, _, win32err = glpi.Call(uintptr(unsafe.Pointer(&b[0])), uintptr(unsafe.Pointer(&toAllocate))) - if rc == rcFailure { - return nil, fmt.Errorf("GetLogicalProcessorInformation Win32 API call failed to set supplied buffer. Win32 system error: %s", win32err) - } - - for x := uint32(0); x < toAllocate; x += sizeofLogicalProcessorInfo { - lpiraw := b[x : x+sizeofLogicalProcessorInfo] - lpi := &logicalProcessorInfo{ - processorMask: binary.LittleEndian.Uint64(lpiraw[0:]), - relationship: binary.LittleEndian.Uint64(lpiraw[8:]), - } - copy(lpi.dummyunion[0:16], lpiraw[16:32]) - lpis = append(lpis, lpi) - } - return lpis, nil -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/unitutil/unit.go b/vendor/github.com/jaypipes/ghw/pkg/unitutil/unit.go deleted file mode 100644 index 13fa7b5b48..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/unitutil/unit.go +++ /dev/null @@ -1,37 +0,0 @@ -// -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package unitutil - -var ( - KB int64 = 1024 - MB = KB * 1024 - GB = MB * 1024 - TB = GB * 1024 - PB = TB * 1024 - EB = PB * 1024 -) - -// AmountString returns a string representation of the amount with an amount -// suffix corresponding to the nearest kibibit. -// -// For example, AmountString(1022) == "1022). AmountString(1024) == "1KB", etc -func AmountString(size int64) (int64, string) { - switch { - case size < MB: - return KB, "KB" - case size < GB: - return MB, "MB" - case size < TB: - return GB, "GB" - case size < PB: - return TB, "TB" - case size < EB: - return PB, "PB" - default: - return EB, "EB" - } -} diff --git a/vendor/github.com/jaypipes/ghw/pkg/util/util.go b/vendor/github.com/jaypipes/ghw/pkg/util/util.go deleted file mode 100644 index 9b74d7e75f..0000000000 --- a/vendor/github.com/jaypipes/ghw/pkg/util/util.go +++ /dev/null @@ -1,53 +0,0 @@ -// -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package util - -import ( - "fmt" - "io/ioutil" - "os" - "strconv" - "strings" - - "github.com/jaypipes/ghw/pkg/context" -) - -const ( - UNKNOWN = "unknown" - disableWarningsEnv = "GHW_DISABLE_WARNINGS" -) - -type closer interface { - Close() error -} - -func SafeClose(c closer) { - err := c.Close() - if err != nil { - _, _ = fmt.Fprintf(os.Stderr, "failed to close: %s", err) - } -} - -// Reads a supplied filepath and converts the contents to an integer. Returns -// -1 if there were file permissions or existence errors or if the contents -// could not be successfully converted to an integer. In any error, a warning -// message is printed to STDERR and -1 is returned. -func SafeIntFromFile(ctx *context.Context, path string) int { - msg := "failed to read int from file: %s\n" - buf, err := ioutil.ReadFile(path) - if err != nil { - ctx.Warn(msg, err) - return -1 - } - contents := strings.TrimSpace(string(buf)) - res, err := strconv.Atoi(contents) - if err != nil { - ctx.Warn(msg, err) - return -1 - } - return res -} diff --git a/vendor/github.com/jaypipes/pcidb/.get-go-packages.sh b/vendor/github.com/jaypipes/pcidb/.get-go-packages.sh deleted file mode 100644 index 382782f8a1..0000000000 --- a/vendor/github.com/jaypipes/pcidb/.get-go-packages.sh +++ /dev/null @@ -1,3 +0,0 @@ -#! /bin/sh - -export GO_PACKAGES=$(go list ./... | grep -v /vendor/) diff --git a/vendor/github.com/jaypipes/pcidb/.gitignore b/vendor/github.com/jaypipes/pcidb/.gitignore deleted file mode 100644 index cc292d34bc..0000000000 --- a/vendor/github.com/jaypipes/pcidb/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -vendor/ -coverage*.* diff --git a/vendor/github.com/jaypipes/pcidb/.travis.yml b/vendor/github.com/jaypipes/pcidb/.travis.yml deleted file mode 100644 index 2598ce27ae..0000000000 --- a/vendor/github.com/jaypipes/pcidb/.travis.yml +++ /dev/null @@ -1,48 +0,0 @@ -language: go -script: - - source ./.get-go-packages.sh - - go test -v $GO_PACKAGES -matrix: - include: - # On Go 1.10 and Go 1.11, use dep to ensure dependencies before running go - # test. - - os: windows - go: "1.10" - install: - - go get -u github.com/golang/dep/cmd/dep - - dep ensure -v - - os: linux - go: "1.10" - install: - - go get -u github.com/golang/dep/cmd/dep - - dep ensure -v - - os: osx - go: "1.10" - install: - - go get -u github.com/golang/dep/cmd/dep - - dep ensure -v - - os: windows - go: "1.11" - install: - - go get -u github.com/golang/dep/cmd/dep - - dep ensure -v - - os: linux - go: "1.11" - install: - - go get -u github.com/golang/dep/cmd/dep - - dep ensure -v - - os: osx - go: "1.11" - install: - - go get -u github.com/golang/dep/cmd/dep - - dep ensure -v - # On Go 1.12, use go modules to ensure dependencies instead of dep - - os: windows - go: "1.12" - env: GO111MODULE=on - - os: linux - go: "1.12" - env: GO111MODULE=on - - os: osx - go: "1.12" - env: GO111MODULE=on diff --git a/vendor/github.com/jaypipes/pcidb/COPYING b/vendor/github.com/jaypipes/pcidb/COPYING deleted file mode 100644 index 68c771a099..0000000000 --- a/vendor/github.com/jaypipes/pcidb/COPYING +++ /dev/null @@ -1,176 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - diff --git a/vendor/github.com/jaypipes/pcidb/Gopkg.lock b/vendor/github.com/jaypipes/pcidb/Gopkg.lock deleted file mode 100644 index 0030a4eff2..0000000000 --- a/vendor/github.com/jaypipes/pcidb/Gopkg.lock +++ /dev/null @@ -1,17 +0,0 @@ -# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. - - -[[projects]] - digest = "1:78bbb1ba5b7c3f2ed0ea1eab57bdd3859aec7e177811563edc41198a760b06af" - name = "github.com/mitchellh/go-homedir" - packages = ["."] - pruneopts = "UT" - revision = "ae18d6b8b3205b561c79e8e5f69bff09736185f4" - version = "v1.0.0" - -[solve-meta] - analyzer-name = "dep" - analyzer-version = 1 - input-imports = ["github.com/mitchellh/go-homedir"] - solver-name = "gps-cdcl" - solver-version = 1 diff --git a/vendor/github.com/jaypipes/pcidb/Gopkg.toml b/vendor/github.com/jaypipes/pcidb/Gopkg.toml deleted file mode 100644 index 53185c7432..0000000000 --- a/vendor/github.com/jaypipes/pcidb/Gopkg.toml +++ /dev/null @@ -1,34 +0,0 @@ -# Gopkg.toml example -# -# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md -# for detailed Gopkg.toml documentation. -# -# required = ["github.com/user/thing/cmd/thing"] -# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] -# -# [[constraint]] -# name = "github.com/user/project" -# version = "1.0.0" -# -# [[constraint]] -# name = "github.com/user/project2" -# branch = "dev" -# source = "github.com/myfork/project2" -# -# [[override]] -# name = "github.com/x/y" -# version = "2.4.0" -# -# [prune] -# non-go = false -# go-tests = true -# unused-packages = true - - -[prune] - go-tests = true - unused-packages = true - -[[constraint]] - name = "github.com/mitchellh/go-homedir" - version = "1.0.0" diff --git a/vendor/github.com/jaypipes/pcidb/LICENSE b/vendor/github.com/jaypipes/pcidb/LICENSE deleted file mode 100644 index 261eeb9e9f..0000000000 --- a/vendor/github.com/jaypipes/pcidb/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/jaypipes/pcidb/Makefile b/vendor/github.com/jaypipes/pcidb/Makefile deleted file mode 100644 index e6b08dc8e1..0000000000 --- a/vendor/github.com/jaypipes/pcidb/Makefile +++ /dev/null @@ -1,46 +0,0 @@ -VENDOR := vendor -PKGS := $(shell go list ./... | grep -v /$(VENDOR)/) -SRC = $(shell find . -type f -name '*.go' -not -path "*/$(VENDOR)/*") -BIN_DIR := $(GOPATH)/bin -DEP := $(BIN_DIR)/dep -GOMETALINTER := $(BIN_DIR)/gometalinter - -.PHONY: test -test: vet - go test $(PKGS) - -$(DEP): - go get -u github.com/golang/dep/cmd/dep - -.PHONY: dep -dep: $(DEP) - $(DEP) ensure - -$(GOMETALINTER): - go get -u github.com/alecthomas/gometalinter - $(GOMETALINTER) --install &> /dev/null - -.PHONY: lint -lint: $(GOMETALINTER) - $(GOMETALINTER) ./... --vendor - -.PHONY: fmt -fmt: - @gofmt -s -l -w $(SRC) - -.PHONY: fmtcheck -fmtcheck: - @bash -c "diff -u <(echo -n) <(gofmt -d $(SRC))" - -.PHONY: vet -vet: - go vet $(PKGS) - -.PHONY: cover -cover: - $(shell [ -e coverage.out ] && rm coverage.out) - @echo "mode: count" > coverage-all.out - @$(foreach pkg,$(PKGS),\ - go test -coverprofile=coverage.out -covermode=count $(pkg);\ - tail -n +2 coverage.out >> coverage-all.out;) - go tool cover -html=coverage-all.out -o=coverage-all.html diff --git a/vendor/github.com/jaypipes/pcidb/README.md b/vendor/github.com/jaypipes/pcidb/README.md deleted file mode 100644 index fd2915b4ee..0000000000 --- a/vendor/github.com/jaypipes/pcidb/README.md +++ /dev/null @@ -1,413 +0,0 @@ -# `pcidb` - the Golang PCI DB library [![Build Status](https://travis-ci.org/jaypipes/pcidb.svg?branch=master)](https://travis-ci.org/jaypipes/pcidb) - -`pcidb` is a small Golang library for programmatic querying of PCI vendor, -product and class information. - -We currently [test](https://travis-ci.org/jaypipes/pcidb/) `pcidb` on Linux, Windows and MacOSX. - -## Usage - -`pcidb` contains a PCI database inspection and querying facility that allows -developers to query for information about hardware device classes, vendor and -product information. - -The `pcidb.New()` function returns a `pcidb.PCIDB` struct or an error if the -PCI database could not be loaded. - -> `pcidb`'s default behaviour is to first search for pci-ids DB files on the -> local host system in well-known filesystem paths. If `pcidb` cannot find a -> pci-ids DB file on the local host system, it will then fetch a current -> pci-ids DB file from the network. You can disable this network-fetching -> behaviour with the `pcidb.WithDisableNetworkFetch()` function or set the -> `PCIDB_DISABLE_NETWORK_FETCH` to a non-0 value. - -The `pcidb.PCIDB` struct contains a number of fields that may be queried for -PCI information: - -* `pcidb.PCIDB.Classes` is a map, keyed by the PCI class ID (a hex-encoded - string) of pointers to `pcidb.Class` structs, one for each class of PCI - device known to `pcidb` -* `pcidb.PCIDB.Vendors` is a map, keyed by the PCI vendor ID (a hex-encoded - string) of pointers to `pcidb.Vendor` structs, one for each PCI vendor - known to `pcidb` -* `pcidb.PCIDB.Products` is a map, keyed by the PCI product ID* (a hex-encoded - string) of pointers to `pcidb.Product` structs, one for each PCI product - known to `pcidb` - -**NOTE**: PCI products are often referred to by their "device ID". We use -the term "product ID" in `pcidb` because it more accurately reflects what the -identifier is for: a specific product line produced by the vendor. - -### Overriding the root mountpoint `pcidb` uses - -The default root mountpoint that `pcidb` uses when looking for information -about the host system is `/`. So, for example, when looking up known PCI IDS DB -files on Linux, `pcidb` will attempt to discover a pciids DB file at -`/usr/share/misc/pci.ids`. If you are calling `pcidb` from a system that has an -alternate root mountpoint, you can either set the `PCIDB_CHROOT` environment -variable to that alternate path, or call the `pcidb.New()` function with the -`pcidb.WithChroot()` modifier. - -For example, if you are executing from within an application container that has -bind-mounted the root host filesystem to the mount point `/host`, you would set -`PCIDB_CHROOT` to `/host` so that pcidb can find files like -`/usr/share/misc/pci.ids` at `/host/usr/share/misc/pci.ids`. - -Alternately, you can use the `pcidb.WithChroot()` function like so: - -```go -pci := pcidb.New(pcidb.WithChroot("/host")) -``` - -### PCI device classes - -Let's take a look at the PCI device class information and how to query the PCI -database for class, subclass, and programming interface information. - -Each `pcidb.Class` struct contains the following fields: - -* `pcidb.Class.ID` is the hex-encoded string identifier for the device - class -* `pcidb.Class.Name` is the common name/description of the class -* `pcidb.Class.Subclasses` is an array of pointers to - `pcidb.Subclass` structs, one for each subclass in the device class - -Each `pcidb.Subclass` struct contains the following fields: - -* `pcidb.Subclass.ID` is the hex-encoded string identifier for the device - subclass -* `pcidb.Subclass.Name` is the common name/description of the subclass -* `pcidb.Subclass.ProgrammingInterfaces` is an array of pointers to - `pcidb.ProgrammingInterface` structs, one for each programming interface - for the device subclass - -Each `pcidb.ProgrammingInterface` struct contains the following fields: - -* `pcidb.ProgrammingInterface.ID` is the hex-encoded string identifier for - the programming interface -* `pcidb.ProgrammingInterface.Name` is the common name/description for the - programming interface - -```go -package main - -import ( - "fmt" - - "github.com/jaypipes/pcidb" -) - -func main() { - pci, err := pcidb.New() - if err != nil { - fmt.Printf("Error getting PCI info: %v", err) - } - - for _, devClass := range pci.Classes { - fmt.Printf(" Device class: %v ('%v')\n", devClass.Name, devClass.ID) - for _, devSubclass := range devClass.Subclasses { - fmt.Printf(" Device subclass: %v ('%v')\n", devSubclass.Name, devSubclass.ID) - for _, progIface := range devSubclass.ProgrammingInterfaces { - fmt.Printf(" Programming interface: %v ('%v')\n", progIface.Name, progIface.ID) - } - } - } -} -``` - -Example output from my personal workstation, snipped for brevity: - -``` -... - Device class: Serial bus controller ('0c') - Device subclass: FireWire (IEEE 1394) ('00') - Programming interface: Generic ('00') - Programming interface: OHCI ('10') - Device subclass: ACCESS Bus ('01') - Device subclass: SSA ('02') - Device subclass: USB controller ('03') - Programming interface: UHCI ('00') - Programming interface: OHCI ('10') - Programming interface: EHCI ('20') - Programming interface: XHCI ('30') - Programming interface: Unspecified ('80') - Programming interface: USB Device ('fe') - Device subclass: Fibre Channel ('04') - Device subclass: SMBus ('05') - Device subclass: InfiniBand ('06') - Device subclass: IPMI SMIC interface ('07') - Device subclass: SERCOS interface ('08') - Device subclass: CANBUS ('09') -... -``` - -### PCI vendors and products - -Let's take a look at the PCI vendor information and how to query the PCI -database for vendor information and the products a vendor supplies. - -Each `pcidb.Vendor` struct contains the following fields: - -* `pcidb.Vendor.ID` is the hex-encoded string identifier for the vendor -* `pcidb.Vendor.Name` is the common name/description of the vendor -* `pcidb.Vendor.Products` is an array of pointers to `pcidb.Product` - structs, one for each product supplied by the vendor - -Each `pcidb.Product` struct contains the following fields: - -* `pcidb.Product.VendorID` is the hex-encoded string identifier for the - product's vendor -* `pcidb.Product.ID` is the hex-encoded string identifier for the product -* `pcidb.Product.Name` is the common name/description of the subclass -* `pcidb.Product.Subsystems` is an array of pointers to - `pcidb.Product` structs, one for each "subsystem" (sometimes called - "sub-device" in PCI literature) for the product - -**NOTE**: A subsystem product may have a different vendor than its "parent" PCI -product. This is sometimes referred to as the "sub-vendor". - -Here's some example code that demonstrates listing the PCI vendors with the -most known products: - -```go -package main - -import ( - "fmt" - "sort" - - "github.com/jaypipes/pcidb" -) - -type ByCountProducts []*pcidb.Vendor - -func (v ByCountProducts) Len() int { - return len(v) -} - -func (v ByCountProducts) Swap(i, j int) { - v[i], v[j] = v[j], v[i] -} - -func (v ByCountProducts) Less(i, j int) bool { - return len(v[i].Products) > len(v[j].Products) -} - -func main() { - pci, err := pcidb.New() - if err != nil { - fmt.Printf("Error getting PCI info: %v", err) - } - - vendors := make([]*pcidb.Vendor, len(pci.Vendors)) - x := 0 - for _, vendor := range pci.Vendors { - vendors[x] = vendor - x++ - } - - sort.Sort(ByCountProducts(vendors)) - - fmt.Println("Top 5 vendors by product") - fmt.Println("====================================================") - for _, vendor := range vendors[0:5] { - fmt.Printf("%v ('%v') has %d products\n", vendor.Name, vendor.ID, len(vendor.Products)) - } -} -``` - -which yields (on my local workstation as of July 7th, 2018): - -``` -Top 5 vendors by product -==================================================== -Intel Corporation ('8086') has 3389 products -NVIDIA Corporation ('10de') has 1358 products -Advanced Micro Devices, Inc. [AMD/ATI] ('1002') has 886 products -National Instruments ('1093') has 601 products -Chelsio Communications Inc ('1425') has 525 products -``` - -The following is an example of querying the PCI product and subsystem -information to find the products which have the most number of subsystems that -have a different vendor than the top-level product. In other words, the two -products which have been re-sold or re-manufactured with the most number of -different companies. - -```go -package main - -import ( - "fmt" - "sort" - - "github.com/jaypipes/pcidb" -) - -type ByCountSeparateSubvendors []*pcidb.Product - -func (v ByCountSeparateSubvendors) Len() int { - return len(v) -} - -func (v ByCountSeparateSubvendors) Swap(i, j int) { - v[i], v[j] = v[j], v[i] -} - -func (v ByCountSeparateSubvendors) Less(i, j int) bool { - iVendor := v[i].VendorID - iSetSubvendors := make(map[string]bool, 0) - iNumDiffSubvendors := 0 - jVendor := v[j].VendorID - jSetSubvendors := make(map[string]bool, 0) - jNumDiffSubvendors := 0 - - for _, sub := range v[i].Subsystems { - if sub.VendorID != iVendor { - iSetSubvendors[sub.VendorID] = true - } - } - iNumDiffSubvendors = len(iSetSubvendors) - - for _, sub := range v[j].Subsystems { - if sub.VendorID != jVendor { - jSetSubvendors[sub.VendorID] = true - } - } - jNumDiffSubvendors = len(jSetSubvendors) - - return iNumDiffSubvendors > jNumDiffSubvendors -} - -func main() { - pci, err := pcidb.New() - if err != nil { - fmt.Printf("Error getting PCI info: %v", err) - } - - products := make([]*pcidb.Product, len(pci.Products)) - x := 0 - for _, product := range pci.Products { - products[x] = product - x++ - } - - sort.Sort(ByCountSeparateSubvendors(products)) - - fmt.Println("Top 2 products by # different subvendors") - fmt.Println("====================================================") - for _, product := range products[0:2] { - vendorID := product.VendorID - vendor := pci.Vendors[vendorID] - setSubvendors := make(map[string]bool, 0) - - for _, sub := range product.Subsystems { - if sub.VendorID != vendorID { - setSubvendors[sub.VendorID] = true - } - } - fmt.Printf("%v ('%v') from %v\n", product.Name, product.ID, vendor.Name) - fmt.Printf(" -> %d subsystems under the following different vendors:\n", len(setSubvendors)) - for subvendorID, _ := range setSubvendors { - subvendor, exists := pci.Vendors[subvendorID] - subvendorName := "Unknown subvendor" - if exists { - subvendorName = subvendor.Name - } - fmt.Printf(" - %v ('%v')\n", subvendorName, subvendorID) - } - } -} -``` - -which yields (on my local workstation as of July 7th, 2018): - -``` -Top 2 products by # different subvendors -==================================================== -RTL-8100/8101L/8139 PCI Fast Ethernet Adapter ('8139') from Realtek Semiconductor Co., Ltd. - -> 34 subsystems under the following different vendors: - - OVISLINK Corp. ('149c') - - EPoX Computer Co., Ltd. ('1695') - - Red Hat, Inc ('1af4') - - Mitac ('1071') - - Netgear ('1385') - - Micro-Star International Co., Ltd. [MSI] ('1462') - - Hangzhou Silan Microelectronics Co., Ltd. ('1904') - - Compex ('11f6') - - Edimax Computer Co. ('1432') - - KYE Systems Corporation ('1489') - - ZyXEL Communications Corporation ('187e') - - Acer Incorporated [ALI] ('1025') - - Matsushita Electric Industrial Co., Ltd. ('10f7') - - Ruby Tech Corp. ('146c') - - Belkin ('1799') - - Allied Telesis ('1259') - - Unex Technology Corp. ('1429') - - CIS Technology Inc ('1436') - - D-Link System Inc ('1186') - - Ambicom Inc ('1395') - - AOPEN Inc. ('a0a0') - - TTTech Computertechnik AG (Wrong ID) ('0357') - - Gigabyte Technology Co., Ltd ('1458') - - Packard Bell B.V. ('1631') - - Billionton Systems Inc ('14cb') - - Kingston Technologies ('2646') - - Accton Technology Corporation ('1113') - - Samsung Electronics Co Ltd ('144d') - - Biostar Microtech Int'l Corp ('1565') - - U.S. Robotics ('16ec') - - KTI ('8e2e') - - Hewlett-Packard Company ('103c') - - ASUSTeK Computer Inc. ('1043') - - Surecom Technology ('10bd') -Bt878 Video Capture ('036e') from Brooktree Corporation - -> 30 subsystems under the following different vendors: - - iTuner ('aa00') - - Nebula Electronics Ltd. ('0071') - - DViCO Corporation ('18ac') - - iTuner ('aa05') - - iTuner ('aa0d') - - LeadTek Research Inc. ('107d') - - Avermedia Technologies Inc ('1461') - - Chaintech Computer Co. Ltd ('270f') - - iTuner ('aa07') - - iTuner ('aa0a') - - Microtune, Inc. ('1851') - - iTuner ('aa01') - - iTuner ('aa04') - - iTuner ('aa06') - - iTuner ('aa0f') - - iTuner ('aa02') - - iTuner ('aa0b') - - Pinnacle Systems, Inc. (Wrong ID) ('bd11') - - Rockwell International ('127a') - - Askey Computer Corp. ('144f') - - Twinhan Technology Co. Ltd ('1822') - - Anritsu Corp. ('1852') - - iTuner ('aa08') - - Hauppauge computer works Inc. ('0070') - - Pinnacle Systems Inc. ('11bd') - - Conexant Systems, Inc. ('14f1') - - iTuner ('aa09') - - iTuner ('aa03') - - iTuner ('aa0c') - - iTuner ('aa0e') -``` - -## Developers - -Contributions to `pcidb` are welcomed! Fork the repo on GitHub and submit a pull -request with your proposed changes. Or, feel free to log an issue for a feature -request or bug report. - -### Running tests - -You can run unit tests easily using the `make test` command, like so: - - -``` -[jaypipes@uberbox pcidb]$ make test -go test github.com/jaypipes/pcidb -ok github.com/jaypipes/pcidb 0.045s -``` diff --git a/vendor/github.com/jaypipes/pcidb/context.go b/vendor/github.com/jaypipes/pcidb/context.go deleted file mode 100644 index 946124d9e7..0000000000 --- a/vendor/github.com/jaypipes/pcidb/context.go +++ /dev/null @@ -1,86 +0,0 @@ -package pcidb - -import ( - "fmt" - "os" - "path/filepath" - "runtime" - - homedir "github.com/mitchellh/go-homedir" -) - -// Concrete merged set of configuration switches that get passed to pcidb -// internal functions -type context struct { - chroot string - cacheOnly bool - cachePath string - path string - disableNetworkFetch bool - searchPaths []string -} - -func contextFromOptions(merged *WithOption) *context { - ctx := &context{ - chroot: *merged.Chroot, - cacheOnly: *merged.CacheOnly, - cachePath: getCachePath(), - disableNetworkFetch: *merged.DisableNetworkFetch, - path: *merged.Path, - searchPaths: make([]string, 0), - } - ctx.setSearchPaths() - return ctx -} - -func getCachePath() string { - hdir, err := homedir.Dir() - if err != nil { - fmt.Fprintf(os.Stderr, "Failed getting homedir.Dir(): %v", err) - return "" - } - fp, err := homedir.Expand(filepath.Join(hdir, ".cache", "pci.ids")) - if err != nil { - fmt.Fprintf(os.Stderr, "Failed expanding local cache path: %v", err) - return "" - } - return fp -} - -// Depending on the operating system, sets the context's searchPaths to a set -// of local filepaths to search for a pci.ids database file -func (ctx *context) setSearchPaths() { - // Look in direct path first, if set - if ctx.path != "" { - ctx.searchPaths = append(ctx.searchPaths, ctx.path) - return - } - // A set of filepaths we will first try to search for the pci-ids DB file - // on the local machine. If we fail to find one, we'll try pulling the - // latest pci-ids file from the network - ctx.searchPaths = append(ctx.searchPaths, ctx.cachePath) - if ctx.cacheOnly { - return - } - - rootPath := ctx.chroot - - if runtime.GOOS != "windows" { - ctx.searchPaths = append( - ctx.searchPaths, - filepath.Join(rootPath, "usr", "share", "hwdata", "pci.ids"), - ) - ctx.searchPaths = append( - ctx.searchPaths, - filepath.Join(rootPath, "usr", "share", "misc", "pci.ids"), - ) - ctx.searchPaths = append( - ctx.searchPaths, - filepath.Join(rootPath, "usr", "share", "hwdata", "pci.ids.gz"), - ) - ctx.searchPaths = append( - ctx.searchPaths, - filepath.Join(rootPath, "usr", "share", "misc", "pci.ids.gz"), - ) - } -} diff --git a/vendor/github.com/jaypipes/pcidb/discover.go b/vendor/github.com/jaypipes/pcidb/discover.go deleted file mode 100644 index 38f92a2a73..0000000000 --- a/vendor/github.com/jaypipes/pcidb/discover.go +++ /dev/null @@ -1,111 +0,0 @@ -// -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package pcidb - -import ( - "bufio" - "compress/gzip" - "io" - "net/http" - "os" - "path/filepath" - "strings" -) - -const ( - PCIIDS_URI = "https://pci-ids.ucw.cz/v2.2/pci.ids.gz" - USER_AGENT = "golang-jaypipes-pcidb" -) - -func (db *PCIDB) load(ctx *context) error { - var foundPath string - for _, fp := range ctx.searchPaths { - if _, err := os.Stat(fp); err == nil { - foundPath = fp - break - } - } - if foundPath == "" { - if ctx.disableNetworkFetch { - return ERR_NO_DB - } - // OK, so we didn't find any host-local copy of the pci-ids DB file. Let's - // try fetching it from the network and storing it - if err := cacheDBFile(ctx.cachePath); err != nil { - return err - } - foundPath = ctx.cachePath - } - f, err := os.Open(foundPath) - if err != nil { - return err - } - defer f.Close() - - var scanner *bufio.Scanner - if strings.HasSuffix(foundPath, ".gz") { - var zipReader *gzip.Reader - if zipReader, err = gzip.NewReader(f); err != nil { - return err - } - defer zipReader.Close() - scanner = bufio.NewScanner(zipReader) - } else { - scanner = bufio.NewScanner(f) - } - - return parseDBFile(db, scanner) -} - -func ensureDir(fp string) error { - fpDir := filepath.Dir(fp) - if _, err := os.Stat(fpDir); os.IsNotExist(err) { - err = os.MkdirAll(fpDir, os.ModePerm) - if err != nil { - return err - } - } - return nil -} - -// Pulls down the latest copy of the pci-ids file from the network and stores -// it in the local host filesystem -func cacheDBFile(cacheFilePath string) error { - ensureDir(cacheFilePath) - - client := new(http.Client) - request, err := http.NewRequest("GET", PCIIDS_URI, nil) - if err != nil { - return err - } - request.Header.Set("User-Agent", USER_AGENT) - response, err := client.Do(request) - if err != nil { - return err - } - defer response.Body.Close() - f, err := os.Create(cacheFilePath) - if err != nil { - return err - } - defer func() { - if err != nil { - os.Remove(cacheFilePath) - } - }() - defer f.Close() - // write the gunzipped contents to our local cache file - zr, err := gzip.NewReader(response.Body) - if err != nil { - return err - } - defer zr.Close() - if _, err = io.Copy(f, zr); err != nil { - return err - } - return err -} diff --git a/vendor/github.com/jaypipes/pcidb/main.go b/vendor/github.com/jaypipes/pcidb/main.go deleted file mode 100644 index 3768bab2e0..0000000000 --- a/vendor/github.com/jaypipes/pcidb/main.go +++ /dev/null @@ -1,198 +0,0 @@ -// -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package pcidb - -import ( - "fmt" - "os" - "strconv" -) - -var ( - ERR_NO_DB = fmt.Errorf("No pci-ids DB files found (and network fetch disabled)") - trueVar = true -) - -// ProgrammingInterface is the PCI programming interface for a class of PCI -// devices -type ProgrammingInterface struct { - // hex-encoded PCI_ID of the programming interface - ID string `json:"id"` - // common string name for the programming interface - Name string `json:"name"` -} - -// Subclass is a subdivision of a PCI class -type Subclass struct { - // hex-encoded PCI_ID for the device subclass - ID string `json:"id"` - // common string name for the subclass - Name string `json:"name"` - // any programming interfaces this subclass might have - ProgrammingInterfaces []*ProgrammingInterface `json:"programming_interfaces"` -} - -// Class is the PCI class -type Class struct { - // hex-encoded PCI_ID for the device class - ID string `json:"id"` - // common string name for the class - Name string `json:"name"` - // any subclasses belonging to this class - Subclasses []*Subclass `json:"subclasses"` -} - -// Product provides information about a PCI device model -// NOTE(jaypipes): In the hardware world, the PCI "device_id" is the identifier -// for the product/model -type Product struct { - // vendor ID for the product - VendorID string `json:"vendor_id"` - // hex-encoded PCI_ID for the product/model - ID string `json:"id"` - // common string name of the vendor - Name string `json:"name"` - // "subdevices" or "subsystems" for the product - Subsystems []*Product `json:"subsystems"` -} - -// Vendor provides information about a device vendor -type Vendor struct { - // hex-encoded PCI_ID for the vendor - ID string `json:"id"` - // common string name of the vendor - Name string `json:"name"` - // all top-level devices for the vendor - Products []*Product `json:"products"` -} - -type PCIDB struct { - // hash of class ID -> class information - Classes map[string]*Class `json:"classes"` - // hash of vendor ID -> vendor information - Vendors map[string]*Vendor `json:"vendors"` - // hash of vendor ID + product/device ID -> product information - Products map[string]*Product `json:"products"` -} - -// WithOption is used to represent optionally-configured settings -type WithOption struct { - // Chroot is the directory that pcidb uses when attempting to discover - // pciids DB files - Chroot *string - // CacheOnly is mostly just useful for testing. It essentially disables - // looking for any non ~/.cache/pci.ids filepaths (which is useful when we - // want to test the fetch-from-network code paths - CacheOnly *bool - // Disables the default behaviour of fetching a pci-ids from a known - // location on the network if no local pci-ids DB files can be found. - // Useful for secure environments or environments with no network - // connectivity. - DisableNetworkFetch *bool - // Path points to the absolute path of a pci.ids file in a non-standard - // location. - Path *string -} - -func WithChroot(dir string) *WithOption { - return &WithOption{Chroot: &dir} -} - -func WithCacheOnly() *WithOption { - return &WithOption{CacheOnly: &trueVar} -} - -func WithDirectPath(path string) *WithOption { - return &WithOption{Path: &path} -} - -func WithDisableNetworkFetch() *WithOption { - return &WithOption{DisableNetworkFetch: &trueVar} -} - -func mergeOptions(opts ...*WithOption) *WithOption { - // Grab options from the environs by default - defaultChroot := "/" - if val, exists := os.LookupEnv("PCIDB_CHROOT"); exists { - defaultChroot = val - } - path := "" - if val, exists := os.LookupEnv("PCIDB_PATH"); exists { - path = val - } - defaultCacheOnly := false - if val, exists := os.LookupEnv("PCIDB_CACHE_ONLY"); exists { - if parsed, err := strconv.ParseBool(val); err != nil { - fmt.Fprintf( - os.Stderr, - "Failed parsing a bool from PCIDB_CACHE_ONLY "+ - "environ value of %s", - val, - ) - } else if parsed { - defaultCacheOnly = parsed - } - } - defaultDisableNetworkFetch := false - if val, exists := os.LookupEnv("PCIDB_DISABLE_NETWORK_FETCH"); exists { - if parsed, err := strconv.ParseBool(val); err != nil { - fmt.Fprintf( - os.Stderr, - "Failed parsing a bool from PCIDB_DISABLE_NETWORK_FETCH "+ - "environ value of %s", - val, - ) - } else if parsed { - defaultDisableNetworkFetch = parsed - } - } - - merged := &WithOption{} - for _, opt := range opts { - if opt.Chroot != nil { - merged.Chroot = opt.Chroot - } - if opt.CacheOnly != nil { - merged.CacheOnly = opt.CacheOnly - } - if opt.DisableNetworkFetch != nil { - merged.DisableNetworkFetch = opt.DisableNetworkFetch - } - if opt.Path != nil { - merged.Path = opt.Path - } - } - // Set the default value if missing from merged - if merged.Chroot == nil { - merged.Chroot = &defaultChroot - } - if merged.CacheOnly == nil { - merged.CacheOnly = &defaultCacheOnly - } - if merged.DisableNetworkFetch == nil { - merged.DisableNetworkFetch = &defaultDisableNetworkFetch - } - if merged.Path == nil { - merged.Path = &path - } - return merged -} - -// New returns a pointer to a PCIDB struct which contains information you can -// use to query PCI vendor, product and class information. It accepts zero or -// more pointers to WithOption structs. If you want to modify the behaviour of -// pcidb, use one of the option modifiers when calling New. For example, to -// change the root directory that pcidb uses when discovering pciids DB files, -// call New(WithChroot("/my/root/override")) -func New(opts ...*WithOption) (*PCIDB, error) { - ctx := contextFromOptions(mergeOptions(opts...)) - db := &PCIDB{} - if err := db.load(ctx); err != nil { - return nil, err - } - return db, nil -} diff --git a/vendor/github.com/jaypipes/pcidb/parse.go b/vendor/github.com/jaypipes/pcidb/parse.go deleted file mode 100644 index 0fee5fe5e0..0000000000 --- a/vendor/github.com/jaypipes/pcidb/parse.go +++ /dev/null @@ -1,163 +0,0 @@ -// -// Use and distribution licensed under the Apache license version 2. -// -// See the COPYING file in the root project directory for full text. -// - -package pcidb - -import ( - "bufio" - "strings" -) - -func parseDBFile(db *PCIDB, scanner *bufio.Scanner) error { - inClassBlock := false - db.Classes = make(map[string]*Class, 20) - db.Vendors = make(map[string]*Vendor, 200) - db.Products = make(map[string]*Product, 1000) - subclasses := make([]*Subclass, 0) - progIfaces := make([]*ProgrammingInterface, 0) - var curClass *Class - var curSubclass *Subclass - var curProgIface *ProgrammingInterface - vendorProducts := make([]*Product, 0) - var curVendor *Vendor - var curProduct *Product - var curSubsystem *Product - productSubsystems := make([]*Product, 0) - for scanner.Scan() { - line := scanner.Text() - // skip comments and blank lines - if line == "" || strings.HasPrefix(line, "#") { - continue - } - lineBytes := []rune(line) - - // Lines starting with an uppercase "C" indicate a PCI top-level class - // dbrmation block. These lines look like this: - // - // C 02 Network controller - if lineBytes[0] == 'C' { - if curClass != nil { - // finalize existing class because we found a new class block - curClass.Subclasses = subclasses - subclasses = make([]*Subclass, 0) - } - inClassBlock = true - classID := string(lineBytes[2:4]) - className := string(lineBytes[6:]) - curClass = &Class{ - ID: classID, - Name: className, - Subclasses: subclasses, - } - db.Classes[curClass.ID] = curClass - continue - } - - // Lines not beginning with an uppercase "C" or a TAB character - // indicate a top-level vendor dbrmation block. These lines look like - // this: - // - // 0a89 BREA Technologies Inc - if lineBytes[0] != '\t' { - if curVendor != nil { - // finalize existing vendor because we found a new vendor block - curVendor.Products = vendorProducts - vendorProducts = make([]*Product, 0) - } - inClassBlock = false - vendorID := string(lineBytes[0:4]) - vendorName := string(lineBytes[6:]) - curVendor = &Vendor{ - ID: vendorID, - Name: vendorName, - Products: vendorProducts, - } - db.Vendors[curVendor.ID] = curVendor - continue - } - - // Lines beginning with only a single TAB character are *either* a - // subclass OR are a device dbrmation block. If we're in a class - // block (i.e. the last parsed block header was for a PCI class), then - // we parse a subclass block. Otherwise, we parse a device dbrmation - // block. - // - // A subclass dbrmation block looks like this: - // - // \t00 Non-VGA unclassified device - // - // A device dbrmation block looks like this: - // - // \t0002 PCI to MCA Bridge - if len(lineBytes) > 1 && lineBytes[1] != '\t' { - if inClassBlock { - if curSubclass != nil { - // finalize existing subclass because we found a new subclass block - curSubclass.ProgrammingInterfaces = progIfaces - progIfaces = make([]*ProgrammingInterface, 0) - } - subclassID := string(lineBytes[1:3]) - subclassName := string(lineBytes[5:]) - curSubclass = &Subclass{ - ID: subclassID, - Name: subclassName, - ProgrammingInterfaces: progIfaces, - } - subclasses = append(subclasses, curSubclass) - } else { - if curProduct != nil { - // finalize existing product because we found a new product block - curProduct.Subsystems = productSubsystems - productSubsystems = make([]*Product, 0) - } - productID := string(lineBytes[1:5]) - productName := string(lineBytes[7:]) - productKey := curVendor.ID + productID - curProduct = &Product{ - VendorID: curVendor.ID, - ID: productID, - Name: productName, - } - vendorProducts = append(vendorProducts, curProduct) - db.Products[productKey] = curProduct - } - } else { - // Lines beginning with two TAB characters are *either* a subsystem - // (subdevice) OR are a programming interface for a PCI device - // subclass. If we're in a class block (i.e. the last parsed block - // header was for a PCI class), then we parse a programming - // interface block, otherwise we parse a subsystem block. - // - // A programming interface block looks like this: - // - // \t\t00 UHCI - // - // A subsystem block looks like this: - // - // \t\t0e11 4091 Smart Array 6i - if inClassBlock { - progIfaceID := string(lineBytes[2:4]) - progIfaceName := string(lineBytes[6:]) - curProgIface = &ProgrammingInterface{ - ID: progIfaceID, - Name: progIfaceName, - } - progIfaces = append(progIfaces, curProgIface) - } else { - vendorID := string(lineBytes[2:6]) - subsystemID := string(lineBytes[7:11]) - subsystemName := string(lineBytes[13:]) - curSubsystem = &Product{ - VendorID: vendorID, - ID: subsystemID, - Name: subsystemName, - } - productSubsystems = append(productSubsystems, curSubsystem) - } - } - } - return nil -} diff --git a/vendor/github.com/mitchellh/go-homedir/LICENSE b/vendor/github.com/mitchellh/go-homedir/LICENSE deleted file mode 100644 index f9c841a51e..0000000000 --- a/vendor/github.com/mitchellh/go-homedir/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2013 Mitchell Hashimoto - -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. diff --git a/vendor/github.com/mitchellh/go-homedir/README.md b/vendor/github.com/mitchellh/go-homedir/README.md deleted file mode 100644 index d70706d5b3..0000000000 --- a/vendor/github.com/mitchellh/go-homedir/README.md +++ /dev/null @@ -1,14 +0,0 @@ -# go-homedir - -This is a Go library for detecting the user's home directory without -the use of cgo, so the library can be used in cross-compilation environments. - -Usage is incredibly simple, just call `homedir.Dir()` to get the home directory -for a user, and `homedir.Expand()` to expand the `~` in a path to the home -directory. - -**Why not just use `os/user`?** The built-in `os/user` package requires -cgo on Darwin systems. This means that any Go code that uses that package -cannot cross compile. But 99% of the time the use for `os/user` is just to -retrieve the home directory, which we can do for the current user without -cgo. This library does that, enabling cross-compilation. diff --git a/vendor/github.com/mitchellh/go-homedir/homedir.go b/vendor/github.com/mitchellh/go-homedir/homedir.go deleted file mode 100644 index 25378537ea..0000000000 --- a/vendor/github.com/mitchellh/go-homedir/homedir.go +++ /dev/null @@ -1,167 +0,0 @@ -package homedir - -import ( - "bytes" - "errors" - "os" - "os/exec" - "path/filepath" - "runtime" - "strconv" - "strings" - "sync" -) - -// DisableCache will disable caching of the home directory. Caching is enabled -// by default. -var DisableCache bool - -var homedirCache string -var cacheLock sync.RWMutex - -// Dir returns the home directory for the executing user. -// -// This uses an OS-specific method for discovering the home directory. -// An error is returned if a home directory cannot be detected. -func Dir() (string, error) { - if !DisableCache { - cacheLock.RLock() - cached := homedirCache - cacheLock.RUnlock() - if cached != "" { - return cached, nil - } - } - - cacheLock.Lock() - defer cacheLock.Unlock() - - var result string - var err error - if runtime.GOOS == "windows" { - result, err = dirWindows() - } else { - // Unix-like system, so just assume Unix - result, err = dirUnix() - } - - if err != nil { - return "", err - } - homedirCache = result - return result, nil -} - -// Expand expands the path to include the home directory if the path -// is prefixed with `~`. If it isn't prefixed with `~`, the path is -// returned as-is. -func Expand(path string) (string, error) { - if len(path) == 0 { - return path, nil - } - - if path[0] != '~' { - return path, nil - } - - if len(path) > 1 && path[1] != '/' && path[1] != '\\' { - return "", errors.New("cannot expand user-specific home dir") - } - - dir, err := Dir() - if err != nil { - return "", err - } - - return filepath.Join(dir, path[1:]), nil -} - -// Reset clears the cache, forcing the next call to Dir to re-detect -// the home directory. This generally never has to be called, but can be -// useful in tests if you're modifying the home directory via the HOME -// env var or something. -func Reset() { - cacheLock.Lock() - defer cacheLock.Unlock() - homedirCache = "" -} - -func dirUnix() (string, error) { - homeEnv := "HOME" - if runtime.GOOS == "plan9" { - // On plan9, env vars are lowercase. - homeEnv = "home" - } - - // First prefer the HOME environmental variable - if home := os.Getenv(homeEnv); home != "" { - return home, nil - } - - var stdout bytes.Buffer - - // If that fails, try OS specific commands - if runtime.GOOS == "darwin" { - cmd := exec.Command("sh", "-c", `dscl -q . -read /Users/"$(whoami)" NFSHomeDirectory | sed 's/^[^ ]*: //'`) - cmd.Stdout = &stdout - if err := cmd.Run(); err == nil { - result := strings.TrimSpace(stdout.String()) - if result != "" { - return result, nil - } - } - } else { - cmd := exec.Command("getent", "passwd", strconv.Itoa(os.Getuid())) - cmd.Stdout = &stdout - if err := cmd.Run(); err != nil { - // If the error is ErrNotFound, we ignore it. Otherwise, return it. - if err != exec.ErrNotFound { - return "", err - } - } else { - if passwd := strings.TrimSpace(stdout.String()); passwd != "" { - // username:password:uid:gid:gecos:home:shell - passwdParts := strings.SplitN(passwd, ":", 7) - if len(passwdParts) > 5 { - return passwdParts[5], nil - } - } - } - } - - // If all else fails, try the shell - stdout.Reset() - cmd := exec.Command("sh", "-c", "cd && pwd") - cmd.Stdout = &stdout - if err := cmd.Run(); err != nil { - return "", err - } - - result := strings.TrimSpace(stdout.String()) - if result == "" { - return "", errors.New("blank output when reading home directory") - } - - return result, nil -} - -func dirWindows() (string, error) { - // First prefer the HOME environmental variable - if home := os.Getenv("HOME"); home != "" { - return home, nil - } - - // Prefer standard environment variable USERPROFILE - if home := os.Getenv("USERPROFILE"); home != "" { - return home, nil - } - - drive := os.Getenv("HOMEDRIVE") - path := os.Getenv("HOMEPATH") - home := drive + path - if drive == "" || path == "" { - return "", errors.New("HOMEDRIVE, HOMEPATH, or USERPROFILE are blank") - } - - return home, nil -} diff --git a/vendor/gopkg.in/yaml.v2/.travis.yml b/vendor/gopkg.in/yaml.v2/.travis.yml deleted file mode 100644 index 7348c50c0c..0000000000 --- a/vendor/gopkg.in/yaml.v2/.travis.yml +++ /dev/null @@ -1,17 +0,0 @@ -language: go - -go: - - "1.4.x" - - "1.5.x" - - "1.6.x" - - "1.7.x" - - "1.8.x" - - "1.9.x" - - "1.10.x" - - "1.11.x" - - "1.12.x" - - "1.13.x" - - "1.14.x" - - "tip" - -go_import_path: gopkg.in/yaml.v2 diff --git a/vendor/gopkg.in/yaml.v2/LICENSE b/vendor/gopkg.in/yaml.v2/LICENSE deleted file mode 100644 index 8dada3edaf..0000000000 --- a/vendor/gopkg.in/yaml.v2/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/gopkg.in/yaml.v2/LICENSE.libyaml b/vendor/gopkg.in/yaml.v2/LICENSE.libyaml deleted file mode 100644 index 8da58fbf6f..0000000000 --- a/vendor/gopkg.in/yaml.v2/LICENSE.libyaml +++ /dev/null @@ -1,31 +0,0 @@ -The following files were ported to Go from C files of libyaml, and thus -are still covered by their original copyright and license: - - apic.go - emitterc.go - parserc.go - readerc.go - scannerc.go - writerc.go - yamlh.go - yamlprivateh.go - -Copyright (c) 2006 Kirill Simonov - -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. diff --git a/vendor/gopkg.in/yaml.v2/NOTICE b/vendor/gopkg.in/yaml.v2/NOTICE deleted file mode 100644 index 866d74a7ad..0000000000 --- a/vendor/gopkg.in/yaml.v2/NOTICE +++ /dev/null @@ -1,13 +0,0 @@ -Copyright 2011-2016 Canonical Ltd. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/vendor/gopkg.in/yaml.v2/README.md b/vendor/gopkg.in/yaml.v2/README.md deleted file mode 100644 index b50c6e8775..0000000000 --- a/vendor/gopkg.in/yaml.v2/README.md +++ /dev/null @@ -1,133 +0,0 @@ -# YAML support for the Go language - -Introduction ------------- - -The yaml package enables Go programs to comfortably encode and decode YAML -values. It was developed within [Canonical](https://www.canonical.com) as -part of the [juju](https://juju.ubuntu.com) project, and is based on a -pure Go port of the well-known [libyaml](http://pyyaml.org/wiki/LibYAML) -C library to parse and generate YAML data quickly and reliably. - -Compatibility -------------- - -The yaml package supports most of YAML 1.1 and 1.2, including support for -anchors, tags, map merging, etc. Multi-document unmarshalling is not yet -implemented, and base-60 floats from YAML 1.1 are purposefully not -supported since they're a poor design and are gone in YAML 1.2. - -Installation and usage ----------------------- - -The import path for the package is *gopkg.in/yaml.v2*. - -To install it, run: - - go get gopkg.in/yaml.v2 - -API documentation ------------------ - -If opened in a browser, the import path itself leads to the API documentation: - - * [https://gopkg.in/yaml.v2](https://gopkg.in/yaml.v2) - -API stability -------------- - -The package API for yaml v2 will remain stable as described in [gopkg.in](https://gopkg.in). - - -License -------- - -The yaml package is licensed under the Apache License 2.0. Please see the LICENSE file for details. - - -Example -------- - -```Go -package main - -import ( - "fmt" - "log" - - "gopkg.in/yaml.v2" -) - -var data = ` -a: Easy! -b: - c: 2 - d: [3, 4] -` - -// Note: struct fields must be public in order for unmarshal to -// correctly populate the data. -type T struct { - A string - B struct { - RenamedC int `yaml:"c"` - D []int `yaml:",flow"` - } -} - -func main() { - t := T{} - - err := yaml.Unmarshal([]byte(data), &t) - if err != nil { - log.Fatalf("error: %v", err) - } - fmt.Printf("--- t:\n%v\n\n", t) - - d, err := yaml.Marshal(&t) - if err != nil { - log.Fatalf("error: %v", err) - } - fmt.Printf("--- t dump:\n%s\n\n", string(d)) - - m := make(map[interface{}]interface{}) - - err = yaml.Unmarshal([]byte(data), &m) - if err != nil { - log.Fatalf("error: %v", err) - } - fmt.Printf("--- m:\n%v\n\n", m) - - d, err = yaml.Marshal(&m) - if err != nil { - log.Fatalf("error: %v", err) - } - fmt.Printf("--- m dump:\n%s\n\n", string(d)) -} -``` - -This example will generate the following output: - -``` ---- t: -{Easy! {2 [3 4]}} - ---- t dump: -a: Easy! -b: - c: 2 - d: [3, 4] - - ---- m: -map[a:Easy! b:map[c:2 d:[3 4]]] - ---- m dump: -a: Easy! -b: - c: 2 - d: - - 3 - - 4 -``` - diff --git a/vendor/gopkg.in/yaml.v2/apic.go b/vendor/gopkg.in/yaml.v2/apic.go deleted file mode 100644 index acf71402cf..0000000000 --- a/vendor/gopkg.in/yaml.v2/apic.go +++ /dev/null @@ -1,744 +0,0 @@ -package yaml - -import ( - "io" -) - -func yaml_insert_token(parser *yaml_parser_t, pos int, token *yaml_token_t) { - //fmt.Println("yaml_insert_token", "pos:", pos, "typ:", token.typ, "head:", parser.tokens_head, "len:", len(parser.tokens)) - - // Check if we can move the queue at the beginning of the buffer. - if parser.tokens_head > 0 && len(parser.tokens) == cap(parser.tokens) { - if parser.tokens_head != len(parser.tokens) { - copy(parser.tokens, parser.tokens[parser.tokens_head:]) - } - parser.tokens = parser.tokens[:len(parser.tokens)-parser.tokens_head] - parser.tokens_head = 0 - } - parser.tokens = append(parser.tokens, *token) - if pos < 0 { - return - } - copy(parser.tokens[parser.tokens_head+pos+1:], parser.tokens[parser.tokens_head+pos:]) - parser.tokens[parser.tokens_head+pos] = *token -} - -// Create a new parser object. -func yaml_parser_initialize(parser *yaml_parser_t) bool { - *parser = yaml_parser_t{ - raw_buffer: make([]byte, 0, input_raw_buffer_size), - buffer: make([]byte, 0, input_buffer_size), - } - return true -} - -// Destroy a parser object. -func yaml_parser_delete(parser *yaml_parser_t) { - *parser = yaml_parser_t{} -} - -// String read handler. -func yaml_string_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err error) { - if parser.input_pos == len(parser.input) { - return 0, io.EOF - } - n = copy(buffer, parser.input[parser.input_pos:]) - parser.input_pos += n - return n, nil -} - -// Reader read handler. -func yaml_reader_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err error) { - return parser.input_reader.Read(buffer) -} - -// Set a string input. -func yaml_parser_set_input_string(parser *yaml_parser_t, input []byte) { - if parser.read_handler != nil { - panic("must set the input source only once") - } - parser.read_handler = yaml_string_read_handler - parser.input = input - parser.input_pos = 0 -} - -// Set a file input. -func yaml_parser_set_input_reader(parser *yaml_parser_t, r io.Reader) { - if parser.read_handler != nil { - panic("must set the input source only once") - } - parser.read_handler = yaml_reader_read_handler - parser.input_reader = r -} - -// Set the source encoding. -func yaml_parser_set_encoding(parser *yaml_parser_t, encoding yaml_encoding_t) { - if parser.encoding != yaml_ANY_ENCODING { - panic("must set the encoding only once") - } - parser.encoding = encoding -} - -var disableLineWrapping = false - -// Create a new emitter object. -func yaml_emitter_initialize(emitter *yaml_emitter_t) { - *emitter = yaml_emitter_t{ - buffer: make([]byte, output_buffer_size), - raw_buffer: make([]byte, 0, output_raw_buffer_size), - states: make([]yaml_emitter_state_t, 0, initial_stack_size), - events: make([]yaml_event_t, 0, initial_queue_size), - } - if disableLineWrapping { - emitter.best_width = -1 - } -} - -// Destroy an emitter object. -func yaml_emitter_delete(emitter *yaml_emitter_t) { - *emitter = yaml_emitter_t{} -} - -// String write handler. -func yaml_string_write_handler(emitter *yaml_emitter_t, buffer []byte) error { - *emitter.output_buffer = append(*emitter.output_buffer, buffer...) - return nil -} - -// yaml_writer_write_handler uses emitter.output_writer to write the -// emitted text. -func yaml_writer_write_handler(emitter *yaml_emitter_t, buffer []byte) error { - _, err := emitter.output_writer.Write(buffer) - return err -} - -// Set a string output. -func yaml_emitter_set_output_string(emitter *yaml_emitter_t, output_buffer *[]byte) { - if emitter.write_handler != nil { - panic("must set the output target only once") - } - emitter.write_handler = yaml_string_write_handler - emitter.output_buffer = output_buffer -} - -// Set a file output. -func yaml_emitter_set_output_writer(emitter *yaml_emitter_t, w io.Writer) { - if emitter.write_handler != nil { - panic("must set the output target only once") - } - emitter.write_handler = yaml_writer_write_handler - emitter.output_writer = w -} - -// Set the output encoding. -func yaml_emitter_set_encoding(emitter *yaml_emitter_t, encoding yaml_encoding_t) { - if emitter.encoding != yaml_ANY_ENCODING { - panic("must set the output encoding only once") - } - emitter.encoding = encoding -} - -// Set the canonical output style. -func yaml_emitter_set_canonical(emitter *yaml_emitter_t, canonical bool) { - emitter.canonical = canonical -} - -//// Set the indentation increment. -func yaml_emitter_set_indent(emitter *yaml_emitter_t, indent int) { - if indent < 2 || indent > 9 { - indent = 2 - } - emitter.best_indent = indent -} - -// Set the preferred line width. -func yaml_emitter_set_width(emitter *yaml_emitter_t, width int) { - if width < 0 { - width = -1 - } - emitter.best_width = width -} - -// Set if unescaped non-ASCII characters are allowed. -func yaml_emitter_set_unicode(emitter *yaml_emitter_t, unicode bool) { - emitter.unicode = unicode -} - -// Set the preferred line break character. -func yaml_emitter_set_break(emitter *yaml_emitter_t, line_break yaml_break_t) { - emitter.line_break = line_break -} - -///* -// * Destroy a token object. -// */ -// -//YAML_DECLARE(void) -//yaml_token_delete(yaml_token_t *token) -//{ -// assert(token); // Non-NULL token object expected. -// -// switch (token.type) -// { -// case YAML_TAG_DIRECTIVE_TOKEN: -// yaml_free(token.data.tag_directive.handle); -// yaml_free(token.data.tag_directive.prefix); -// break; -// -// case YAML_ALIAS_TOKEN: -// yaml_free(token.data.alias.value); -// break; -// -// case YAML_ANCHOR_TOKEN: -// yaml_free(token.data.anchor.value); -// break; -// -// case YAML_TAG_TOKEN: -// yaml_free(token.data.tag.handle); -// yaml_free(token.data.tag.suffix); -// break; -// -// case YAML_SCALAR_TOKEN: -// yaml_free(token.data.scalar.value); -// break; -// -// default: -// break; -// } -// -// memset(token, 0, sizeof(yaml_token_t)); -//} -// -///* -// * Check if a string is a valid UTF-8 sequence. -// * -// * Check 'reader.c' for more details on UTF-8 encoding. -// */ -// -//static int -//yaml_check_utf8(yaml_char_t *start, size_t length) -//{ -// yaml_char_t *end = start+length; -// yaml_char_t *pointer = start; -// -// while (pointer < end) { -// unsigned char octet; -// unsigned int width; -// unsigned int value; -// size_t k; -// -// octet = pointer[0]; -// width = (octet & 0x80) == 0x00 ? 1 : -// (octet & 0xE0) == 0xC0 ? 2 : -// (octet & 0xF0) == 0xE0 ? 3 : -// (octet & 0xF8) == 0xF0 ? 4 : 0; -// value = (octet & 0x80) == 0x00 ? octet & 0x7F : -// (octet & 0xE0) == 0xC0 ? octet & 0x1F : -// (octet & 0xF0) == 0xE0 ? octet & 0x0F : -// (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0; -// if (!width) return 0; -// if (pointer+width > end) return 0; -// for (k = 1; k < width; k ++) { -// octet = pointer[k]; -// if ((octet & 0xC0) != 0x80) return 0; -// value = (value << 6) + (octet & 0x3F); -// } -// if (!((width == 1) || -// (width == 2 && value >= 0x80) || -// (width == 3 && value >= 0x800) || -// (width == 4 && value >= 0x10000))) return 0; -// -// pointer += width; -// } -// -// return 1; -//} -// - -// Create STREAM-START. -func yaml_stream_start_event_initialize(event *yaml_event_t, encoding yaml_encoding_t) { - *event = yaml_event_t{ - typ: yaml_STREAM_START_EVENT, - encoding: encoding, - } -} - -// Create STREAM-END. -func yaml_stream_end_event_initialize(event *yaml_event_t) { - *event = yaml_event_t{ - typ: yaml_STREAM_END_EVENT, - } -} - -// Create DOCUMENT-START. -func yaml_document_start_event_initialize( - event *yaml_event_t, - version_directive *yaml_version_directive_t, - tag_directives []yaml_tag_directive_t, - implicit bool, -) { - *event = yaml_event_t{ - typ: yaml_DOCUMENT_START_EVENT, - version_directive: version_directive, - tag_directives: tag_directives, - implicit: implicit, - } -} - -// Create DOCUMENT-END. -func yaml_document_end_event_initialize(event *yaml_event_t, implicit bool) { - *event = yaml_event_t{ - typ: yaml_DOCUMENT_END_EVENT, - implicit: implicit, - } -} - -///* -// * Create ALIAS. -// */ -// -//YAML_DECLARE(int) -//yaml_alias_event_initialize(event *yaml_event_t, anchor *yaml_char_t) -//{ -// mark yaml_mark_t = { 0, 0, 0 } -// anchor_copy *yaml_char_t = NULL -// -// assert(event) // Non-NULL event object is expected. -// assert(anchor) // Non-NULL anchor is expected. -// -// if (!yaml_check_utf8(anchor, strlen((char *)anchor))) return 0 -// -// anchor_copy = yaml_strdup(anchor) -// if (!anchor_copy) -// return 0 -// -// ALIAS_EVENT_INIT(*event, anchor_copy, mark, mark) -// -// return 1 -//} - -// Create SCALAR. -func yaml_scalar_event_initialize(event *yaml_event_t, anchor, tag, value []byte, plain_implicit, quoted_implicit bool, style yaml_scalar_style_t) bool { - *event = yaml_event_t{ - typ: yaml_SCALAR_EVENT, - anchor: anchor, - tag: tag, - value: value, - implicit: plain_implicit, - quoted_implicit: quoted_implicit, - style: yaml_style_t(style), - } - return true -} - -// Create SEQUENCE-START. -func yaml_sequence_start_event_initialize(event *yaml_event_t, anchor, tag []byte, implicit bool, style yaml_sequence_style_t) bool { - *event = yaml_event_t{ - typ: yaml_SEQUENCE_START_EVENT, - anchor: anchor, - tag: tag, - implicit: implicit, - style: yaml_style_t(style), - } - return true -} - -// Create SEQUENCE-END. -func yaml_sequence_end_event_initialize(event *yaml_event_t) bool { - *event = yaml_event_t{ - typ: yaml_SEQUENCE_END_EVENT, - } - return true -} - -// Create MAPPING-START. -func yaml_mapping_start_event_initialize(event *yaml_event_t, anchor, tag []byte, implicit bool, style yaml_mapping_style_t) { - *event = yaml_event_t{ - typ: yaml_MAPPING_START_EVENT, - anchor: anchor, - tag: tag, - implicit: implicit, - style: yaml_style_t(style), - } -} - -// Create MAPPING-END. -func yaml_mapping_end_event_initialize(event *yaml_event_t) { - *event = yaml_event_t{ - typ: yaml_MAPPING_END_EVENT, - } -} - -// Destroy an event object. -func yaml_event_delete(event *yaml_event_t) { - *event = yaml_event_t{} -} - -///* -// * Create a document object. -// */ -// -//YAML_DECLARE(int) -//yaml_document_initialize(document *yaml_document_t, -// version_directive *yaml_version_directive_t, -// tag_directives_start *yaml_tag_directive_t, -// tag_directives_end *yaml_tag_directive_t, -// start_implicit int, end_implicit int) -//{ -// struct { -// error yaml_error_type_t -// } context -// struct { -// start *yaml_node_t -// end *yaml_node_t -// top *yaml_node_t -// } nodes = { NULL, NULL, NULL } -// version_directive_copy *yaml_version_directive_t = NULL -// struct { -// start *yaml_tag_directive_t -// end *yaml_tag_directive_t -// top *yaml_tag_directive_t -// } tag_directives_copy = { NULL, NULL, NULL } -// value yaml_tag_directive_t = { NULL, NULL } -// mark yaml_mark_t = { 0, 0, 0 } -// -// assert(document) // Non-NULL document object is expected. -// assert((tag_directives_start && tag_directives_end) || -// (tag_directives_start == tag_directives_end)) -// // Valid tag directives are expected. -// -// if (!STACK_INIT(&context, nodes, INITIAL_STACK_SIZE)) goto error -// -// if (version_directive) { -// version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t)) -// if (!version_directive_copy) goto error -// version_directive_copy.major = version_directive.major -// version_directive_copy.minor = version_directive.minor -// } -// -// if (tag_directives_start != tag_directives_end) { -// tag_directive *yaml_tag_directive_t -// if (!STACK_INIT(&context, tag_directives_copy, INITIAL_STACK_SIZE)) -// goto error -// for (tag_directive = tag_directives_start -// tag_directive != tag_directives_end; tag_directive ++) { -// assert(tag_directive.handle) -// assert(tag_directive.prefix) -// if (!yaml_check_utf8(tag_directive.handle, -// strlen((char *)tag_directive.handle))) -// goto error -// if (!yaml_check_utf8(tag_directive.prefix, -// strlen((char *)tag_directive.prefix))) -// goto error -// value.handle = yaml_strdup(tag_directive.handle) -// value.prefix = yaml_strdup(tag_directive.prefix) -// if (!value.handle || !value.prefix) goto error -// if (!PUSH(&context, tag_directives_copy, value)) -// goto error -// value.handle = NULL -// value.prefix = NULL -// } -// } -// -// DOCUMENT_INIT(*document, nodes.start, nodes.end, version_directive_copy, -// tag_directives_copy.start, tag_directives_copy.top, -// start_implicit, end_implicit, mark, mark) -// -// return 1 -// -//error: -// STACK_DEL(&context, nodes) -// yaml_free(version_directive_copy) -// while (!STACK_EMPTY(&context, tag_directives_copy)) { -// value yaml_tag_directive_t = POP(&context, tag_directives_copy) -// yaml_free(value.handle) -// yaml_free(value.prefix) -// } -// STACK_DEL(&context, tag_directives_copy) -// yaml_free(value.handle) -// yaml_free(value.prefix) -// -// return 0 -//} -// -///* -// * Destroy a document object. -// */ -// -//YAML_DECLARE(void) -//yaml_document_delete(document *yaml_document_t) -//{ -// struct { -// error yaml_error_type_t -// } context -// tag_directive *yaml_tag_directive_t -// -// context.error = YAML_NO_ERROR // Eliminate a compiler warning. -// -// assert(document) // Non-NULL document object is expected. -// -// while (!STACK_EMPTY(&context, document.nodes)) { -// node yaml_node_t = POP(&context, document.nodes) -// yaml_free(node.tag) -// switch (node.type) { -// case YAML_SCALAR_NODE: -// yaml_free(node.data.scalar.value) -// break -// case YAML_SEQUENCE_NODE: -// STACK_DEL(&context, node.data.sequence.items) -// break -// case YAML_MAPPING_NODE: -// STACK_DEL(&context, node.data.mapping.pairs) -// break -// default: -// assert(0) // Should not happen. -// } -// } -// STACK_DEL(&context, document.nodes) -// -// yaml_free(document.version_directive) -// for (tag_directive = document.tag_directives.start -// tag_directive != document.tag_directives.end -// tag_directive++) { -// yaml_free(tag_directive.handle) -// yaml_free(tag_directive.prefix) -// } -// yaml_free(document.tag_directives.start) -// -// memset(document, 0, sizeof(yaml_document_t)) -//} -// -///** -// * Get a document node. -// */ -// -//YAML_DECLARE(yaml_node_t *) -//yaml_document_get_node(document *yaml_document_t, index int) -//{ -// assert(document) // Non-NULL document object is expected. -// -// if (index > 0 && document.nodes.start + index <= document.nodes.top) { -// return document.nodes.start + index - 1 -// } -// return NULL -//} -// -///** -// * Get the root object. -// */ -// -//YAML_DECLARE(yaml_node_t *) -//yaml_document_get_root_node(document *yaml_document_t) -//{ -// assert(document) // Non-NULL document object is expected. -// -// if (document.nodes.top != document.nodes.start) { -// return document.nodes.start -// } -// return NULL -//} -// -///* -// * Add a scalar node to a document. -// */ -// -//YAML_DECLARE(int) -//yaml_document_add_scalar(document *yaml_document_t, -// tag *yaml_char_t, value *yaml_char_t, length int, -// style yaml_scalar_style_t) -//{ -// struct { -// error yaml_error_type_t -// } context -// mark yaml_mark_t = { 0, 0, 0 } -// tag_copy *yaml_char_t = NULL -// value_copy *yaml_char_t = NULL -// node yaml_node_t -// -// assert(document) // Non-NULL document object is expected. -// assert(value) // Non-NULL value is expected. -// -// if (!tag) { -// tag = (yaml_char_t *)YAML_DEFAULT_SCALAR_TAG -// } -// -// if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error -// tag_copy = yaml_strdup(tag) -// if (!tag_copy) goto error -// -// if (length < 0) { -// length = strlen((char *)value) -// } -// -// if (!yaml_check_utf8(value, length)) goto error -// value_copy = yaml_malloc(length+1) -// if (!value_copy) goto error -// memcpy(value_copy, value, length) -// value_copy[length] = '\0' -// -// SCALAR_NODE_INIT(node, tag_copy, value_copy, length, style, mark, mark) -// if (!PUSH(&context, document.nodes, node)) goto error -// -// return document.nodes.top - document.nodes.start -// -//error: -// yaml_free(tag_copy) -// yaml_free(value_copy) -// -// return 0 -//} -// -///* -// * Add a sequence node to a document. -// */ -// -//YAML_DECLARE(int) -//yaml_document_add_sequence(document *yaml_document_t, -// tag *yaml_char_t, style yaml_sequence_style_t) -//{ -// struct { -// error yaml_error_type_t -// } context -// mark yaml_mark_t = { 0, 0, 0 } -// tag_copy *yaml_char_t = NULL -// struct { -// start *yaml_node_item_t -// end *yaml_node_item_t -// top *yaml_node_item_t -// } items = { NULL, NULL, NULL } -// node yaml_node_t -// -// assert(document) // Non-NULL document object is expected. -// -// if (!tag) { -// tag = (yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG -// } -// -// if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error -// tag_copy = yaml_strdup(tag) -// if (!tag_copy) goto error -// -// if (!STACK_INIT(&context, items, INITIAL_STACK_SIZE)) goto error -// -// SEQUENCE_NODE_INIT(node, tag_copy, items.start, items.end, -// style, mark, mark) -// if (!PUSH(&context, document.nodes, node)) goto error -// -// return document.nodes.top - document.nodes.start -// -//error: -// STACK_DEL(&context, items) -// yaml_free(tag_copy) -// -// return 0 -//} -// -///* -// * Add a mapping node to a document. -// */ -// -//YAML_DECLARE(int) -//yaml_document_add_mapping(document *yaml_document_t, -// tag *yaml_char_t, style yaml_mapping_style_t) -//{ -// struct { -// error yaml_error_type_t -// } context -// mark yaml_mark_t = { 0, 0, 0 } -// tag_copy *yaml_char_t = NULL -// struct { -// start *yaml_node_pair_t -// end *yaml_node_pair_t -// top *yaml_node_pair_t -// } pairs = { NULL, NULL, NULL } -// node yaml_node_t -// -// assert(document) // Non-NULL document object is expected. -// -// if (!tag) { -// tag = (yaml_char_t *)YAML_DEFAULT_MAPPING_TAG -// } -// -// if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error -// tag_copy = yaml_strdup(tag) -// if (!tag_copy) goto error -// -// if (!STACK_INIT(&context, pairs, INITIAL_STACK_SIZE)) goto error -// -// MAPPING_NODE_INIT(node, tag_copy, pairs.start, pairs.end, -// style, mark, mark) -// if (!PUSH(&context, document.nodes, node)) goto error -// -// return document.nodes.top - document.nodes.start -// -//error: -// STACK_DEL(&context, pairs) -// yaml_free(tag_copy) -// -// return 0 -//} -// -///* -// * Append an item to a sequence node. -// */ -// -//YAML_DECLARE(int) -//yaml_document_append_sequence_item(document *yaml_document_t, -// sequence int, item int) -//{ -// struct { -// error yaml_error_type_t -// } context -// -// assert(document) // Non-NULL document is required. -// assert(sequence > 0 -// && document.nodes.start + sequence <= document.nodes.top) -// // Valid sequence id is required. -// assert(document.nodes.start[sequence-1].type == YAML_SEQUENCE_NODE) -// // A sequence node is required. -// assert(item > 0 && document.nodes.start + item <= document.nodes.top) -// // Valid item id is required. -// -// if (!PUSH(&context, -// document.nodes.start[sequence-1].data.sequence.items, item)) -// return 0 -// -// return 1 -//} -// -///* -// * Append a pair of a key and a value to a mapping node. -// */ -// -//YAML_DECLARE(int) -//yaml_document_append_mapping_pair(document *yaml_document_t, -// mapping int, key int, value int) -//{ -// struct { -// error yaml_error_type_t -// } context -// -// pair yaml_node_pair_t -// -// assert(document) // Non-NULL document is required. -// assert(mapping > 0 -// && document.nodes.start + mapping <= document.nodes.top) -// // Valid mapping id is required. -// assert(document.nodes.start[mapping-1].type == YAML_MAPPING_NODE) -// // A mapping node is required. -// assert(key > 0 && document.nodes.start + key <= document.nodes.top) -// // Valid key id is required. -// assert(value > 0 && document.nodes.start + value <= document.nodes.top) -// // Valid value id is required. -// -// pair.key = key -// pair.value = value -// -// if (!PUSH(&context, -// document.nodes.start[mapping-1].data.mapping.pairs, pair)) -// return 0 -// -// return 1 -//} -// -// diff --git a/vendor/gopkg.in/yaml.v2/decode.go b/vendor/gopkg.in/yaml.v2/decode.go deleted file mode 100644 index 129bc2a97d..0000000000 --- a/vendor/gopkg.in/yaml.v2/decode.go +++ /dev/null @@ -1,815 +0,0 @@ -package yaml - -import ( - "encoding" - "encoding/base64" - "fmt" - "io" - "math" - "reflect" - "strconv" - "time" -) - -const ( - documentNode = 1 << iota - mappingNode - sequenceNode - scalarNode - aliasNode -) - -type node struct { - kind int - line, column int - tag string - // For an alias node, alias holds the resolved alias. - alias *node - value string - implicit bool - children []*node - anchors map[string]*node -} - -// ---------------------------------------------------------------------------- -// Parser, produces a node tree out of a libyaml event stream. - -type parser struct { - parser yaml_parser_t - event yaml_event_t - doc *node - doneInit bool -} - -func newParser(b []byte) *parser { - p := parser{} - if !yaml_parser_initialize(&p.parser) { - panic("failed to initialize YAML emitter") - } - if len(b) == 0 { - b = []byte{'\n'} - } - yaml_parser_set_input_string(&p.parser, b) - return &p -} - -func newParserFromReader(r io.Reader) *parser { - p := parser{} - if !yaml_parser_initialize(&p.parser) { - panic("failed to initialize YAML emitter") - } - yaml_parser_set_input_reader(&p.parser, r) - return &p -} - -func (p *parser) init() { - if p.doneInit { - return - } - p.expect(yaml_STREAM_START_EVENT) - p.doneInit = true -} - -func (p *parser) destroy() { - if p.event.typ != yaml_NO_EVENT { - yaml_event_delete(&p.event) - } - yaml_parser_delete(&p.parser) -} - -// expect consumes an event from the event stream and -// checks that it's of the expected type. -func (p *parser) expect(e yaml_event_type_t) { - if p.event.typ == yaml_NO_EVENT { - if !yaml_parser_parse(&p.parser, &p.event) { - p.fail() - } - } - if p.event.typ == yaml_STREAM_END_EVENT { - failf("attempted to go past the end of stream; corrupted value?") - } - if p.event.typ != e { - p.parser.problem = fmt.Sprintf("expected %s event but got %s", e, p.event.typ) - p.fail() - } - yaml_event_delete(&p.event) - p.event.typ = yaml_NO_EVENT -} - -// peek peeks at the next event in the event stream, -// puts the results into p.event and returns the event type. -func (p *parser) peek() yaml_event_type_t { - if p.event.typ != yaml_NO_EVENT { - return p.event.typ - } - if !yaml_parser_parse(&p.parser, &p.event) { - p.fail() - } - return p.event.typ -} - -func (p *parser) fail() { - var where string - var line int - if p.parser.problem_mark.line != 0 { - line = p.parser.problem_mark.line - // Scanner errors don't iterate line before returning error - if p.parser.error == yaml_SCANNER_ERROR { - line++ - } - } else if p.parser.context_mark.line != 0 { - line = p.parser.context_mark.line - } - if line != 0 { - where = "line " + strconv.Itoa(line) + ": " - } - var msg string - if len(p.parser.problem) > 0 { - msg = p.parser.problem - } else { - msg = "unknown problem parsing YAML content" - } - failf("%s%s", where, msg) -} - -func (p *parser) anchor(n *node, anchor []byte) { - if anchor != nil { - p.doc.anchors[string(anchor)] = n - } -} - -func (p *parser) parse() *node { - p.init() - switch p.peek() { - case yaml_SCALAR_EVENT: - return p.scalar() - case yaml_ALIAS_EVENT: - return p.alias() - case yaml_MAPPING_START_EVENT: - return p.mapping() - case yaml_SEQUENCE_START_EVENT: - return p.sequence() - case yaml_DOCUMENT_START_EVENT: - return p.document() - case yaml_STREAM_END_EVENT: - // Happens when attempting to decode an empty buffer. - return nil - default: - panic("attempted to parse unknown event: " + p.event.typ.String()) - } -} - -func (p *parser) node(kind int) *node { - return &node{ - kind: kind, - line: p.event.start_mark.line, - column: p.event.start_mark.column, - } -} - -func (p *parser) document() *node { - n := p.node(documentNode) - n.anchors = make(map[string]*node) - p.doc = n - p.expect(yaml_DOCUMENT_START_EVENT) - n.children = append(n.children, p.parse()) - p.expect(yaml_DOCUMENT_END_EVENT) - return n -} - -func (p *parser) alias() *node { - n := p.node(aliasNode) - n.value = string(p.event.anchor) - n.alias = p.doc.anchors[n.value] - if n.alias == nil { - failf("unknown anchor '%s' referenced", n.value) - } - p.expect(yaml_ALIAS_EVENT) - return n -} - -func (p *parser) scalar() *node { - n := p.node(scalarNode) - n.value = string(p.event.value) - n.tag = string(p.event.tag) - n.implicit = p.event.implicit - p.anchor(n, p.event.anchor) - p.expect(yaml_SCALAR_EVENT) - return n -} - -func (p *parser) sequence() *node { - n := p.node(sequenceNode) - p.anchor(n, p.event.anchor) - p.expect(yaml_SEQUENCE_START_EVENT) - for p.peek() != yaml_SEQUENCE_END_EVENT { - n.children = append(n.children, p.parse()) - } - p.expect(yaml_SEQUENCE_END_EVENT) - return n -} - -func (p *parser) mapping() *node { - n := p.node(mappingNode) - p.anchor(n, p.event.anchor) - p.expect(yaml_MAPPING_START_EVENT) - for p.peek() != yaml_MAPPING_END_EVENT { - n.children = append(n.children, p.parse(), p.parse()) - } - p.expect(yaml_MAPPING_END_EVENT) - return n -} - -// ---------------------------------------------------------------------------- -// Decoder, unmarshals a node into a provided value. - -type decoder struct { - doc *node - aliases map[*node]bool - mapType reflect.Type - terrors []string - strict bool - - decodeCount int - aliasCount int - aliasDepth int -} - -var ( - mapItemType = reflect.TypeOf(MapItem{}) - durationType = reflect.TypeOf(time.Duration(0)) - defaultMapType = reflect.TypeOf(map[interface{}]interface{}{}) - ifaceType = defaultMapType.Elem() - timeType = reflect.TypeOf(time.Time{}) - ptrTimeType = reflect.TypeOf(&time.Time{}) -) - -func newDecoder(strict bool) *decoder { - d := &decoder{mapType: defaultMapType, strict: strict} - d.aliases = make(map[*node]bool) - return d -} - -func (d *decoder) terror(n *node, tag string, out reflect.Value) { - if n.tag != "" { - tag = n.tag - } - value := n.value - if tag != yaml_SEQ_TAG && tag != yaml_MAP_TAG { - if len(value) > 10 { - value = " `" + value[:7] + "...`" - } else { - value = " `" + value + "`" - } - } - d.terrors = append(d.terrors, fmt.Sprintf("line %d: cannot unmarshal %s%s into %s", n.line+1, shortTag(tag), value, out.Type())) -} - -func (d *decoder) callUnmarshaler(n *node, u Unmarshaler) (good bool) { - terrlen := len(d.terrors) - err := u.UnmarshalYAML(func(v interface{}) (err error) { - defer handleErr(&err) - d.unmarshal(n, reflect.ValueOf(v)) - if len(d.terrors) > terrlen { - issues := d.terrors[terrlen:] - d.terrors = d.terrors[:terrlen] - return &TypeError{issues} - } - return nil - }) - if e, ok := err.(*TypeError); ok { - d.terrors = append(d.terrors, e.Errors...) - return false - } - if err != nil { - fail(err) - } - return true -} - -// d.prepare initializes and dereferences pointers and calls UnmarshalYAML -// if a value is found to implement it. -// It returns the initialized and dereferenced out value, whether -// unmarshalling was already done by UnmarshalYAML, and if so whether -// its types unmarshalled appropriately. -// -// If n holds a null value, prepare returns before doing anything. -func (d *decoder) prepare(n *node, out reflect.Value) (newout reflect.Value, unmarshaled, good bool) { - if n.tag == yaml_NULL_TAG || n.kind == scalarNode && n.tag == "" && (n.value == "null" || n.value == "~" || n.value == "" && n.implicit) { - return out, false, false - } - again := true - for again { - again = false - if out.Kind() == reflect.Ptr { - if out.IsNil() { - out.Set(reflect.New(out.Type().Elem())) - } - out = out.Elem() - again = true - } - if out.CanAddr() { - if u, ok := out.Addr().Interface().(Unmarshaler); ok { - good = d.callUnmarshaler(n, u) - return out, true, good - } - } - } - return out, false, false -} - -const ( - // 400,000 decode operations is ~500kb of dense object declarations, or - // ~5kb of dense object declarations with 10000% alias expansion - alias_ratio_range_low = 400000 - - // 4,000,000 decode operations is ~5MB of dense object declarations, or - // ~4.5MB of dense object declarations with 10% alias expansion - alias_ratio_range_high = 4000000 - - // alias_ratio_range is the range over which we scale allowed alias ratios - alias_ratio_range = float64(alias_ratio_range_high - alias_ratio_range_low) -) - -func allowedAliasRatio(decodeCount int) float64 { - switch { - case decodeCount <= alias_ratio_range_low: - // allow 99% to come from alias expansion for small-to-medium documents - return 0.99 - case decodeCount >= alias_ratio_range_high: - // allow 10% to come from alias expansion for very large documents - return 0.10 - default: - // scale smoothly from 99% down to 10% over the range. - // this maps to 396,000 - 400,000 allowed alias-driven decodes over the range. - // 400,000 decode operations is ~100MB of allocations in worst-case scenarios (single-item maps). - return 0.99 - 0.89*(float64(decodeCount-alias_ratio_range_low)/alias_ratio_range) - } -} - -func (d *decoder) unmarshal(n *node, out reflect.Value) (good bool) { - d.decodeCount++ - if d.aliasDepth > 0 { - d.aliasCount++ - } - if d.aliasCount > 100 && d.decodeCount > 1000 && float64(d.aliasCount)/float64(d.decodeCount) > allowedAliasRatio(d.decodeCount) { - failf("document contains excessive aliasing") - } - switch n.kind { - case documentNode: - return d.document(n, out) - case aliasNode: - return d.alias(n, out) - } - out, unmarshaled, good := d.prepare(n, out) - if unmarshaled { - return good - } - switch n.kind { - case scalarNode: - good = d.scalar(n, out) - case mappingNode: - good = d.mapping(n, out) - case sequenceNode: - good = d.sequence(n, out) - default: - panic("internal error: unknown node kind: " + strconv.Itoa(n.kind)) - } - return good -} - -func (d *decoder) document(n *node, out reflect.Value) (good bool) { - if len(n.children) == 1 { - d.doc = n - d.unmarshal(n.children[0], out) - return true - } - return false -} - -func (d *decoder) alias(n *node, out reflect.Value) (good bool) { - if d.aliases[n] { - // TODO this could actually be allowed in some circumstances. - failf("anchor '%s' value contains itself", n.value) - } - d.aliases[n] = true - d.aliasDepth++ - good = d.unmarshal(n.alias, out) - d.aliasDepth-- - delete(d.aliases, n) - return good -} - -var zeroValue reflect.Value - -func resetMap(out reflect.Value) { - for _, k := range out.MapKeys() { - out.SetMapIndex(k, zeroValue) - } -} - -func (d *decoder) scalar(n *node, out reflect.Value) bool { - var tag string - var resolved interface{} - if n.tag == "" && !n.implicit { - tag = yaml_STR_TAG - resolved = n.value - } else { - tag, resolved = resolve(n.tag, n.value) - if tag == yaml_BINARY_TAG { - data, err := base64.StdEncoding.DecodeString(resolved.(string)) - if err != nil { - failf("!!binary value contains invalid base64 data") - } - resolved = string(data) - } - } - if resolved == nil { - if out.Kind() == reflect.Map && !out.CanAddr() { - resetMap(out) - } else { - out.Set(reflect.Zero(out.Type())) - } - return true - } - if resolvedv := reflect.ValueOf(resolved); out.Type() == resolvedv.Type() { - // We've resolved to exactly the type we want, so use that. - out.Set(resolvedv) - return true - } - // Perhaps we can use the value as a TextUnmarshaler to - // set its value. - if out.CanAddr() { - u, ok := out.Addr().Interface().(encoding.TextUnmarshaler) - if ok { - var text []byte - if tag == yaml_BINARY_TAG { - text = []byte(resolved.(string)) - } else { - // We let any value be unmarshaled into TextUnmarshaler. - // That might be more lax than we'd like, but the - // TextUnmarshaler itself should bowl out any dubious values. - text = []byte(n.value) - } - err := u.UnmarshalText(text) - if err != nil { - fail(err) - } - return true - } - } - switch out.Kind() { - case reflect.String: - if tag == yaml_BINARY_TAG { - out.SetString(resolved.(string)) - return true - } - if resolved != nil { - out.SetString(n.value) - return true - } - case reflect.Interface: - if resolved == nil { - out.Set(reflect.Zero(out.Type())) - } else if tag == yaml_TIMESTAMP_TAG { - // It looks like a timestamp but for backward compatibility - // reasons we set it as a string, so that code that unmarshals - // timestamp-like values into interface{} will continue to - // see a string and not a time.Time. - // TODO(v3) Drop this. - out.Set(reflect.ValueOf(n.value)) - } else { - out.Set(reflect.ValueOf(resolved)) - } - return true - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - switch resolved := resolved.(type) { - case int: - if !out.OverflowInt(int64(resolved)) { - out.SetInt(int64(resolved)) - return true - } - case int64: - if !out.OverflowInt(resolved) { - out.SetInt(resolved) - return true - } - case uint64: - if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) { - out.SetInt(int64(resolved)) - return true - } - case float64: - if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) { - out.SetInt(int64(resolved)) - return true - } - case string: - if out.Type() == durationType { - d, err := time.ParseDuration(resolved) - if err == nil { - out.SetInt(int64(d)) - return true - } - } - } - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - switch resolved := resolved.(type) { - case int: - if resolved >= 0 && !out.OverflowUint(uint64(resolved)) { - out.SetUint(uint64(resolved)) - return true - } - case int64: - if resolved >= 0 && !out.OverflowUint(uint64(resolved)) { - out.SetUint(uint64(resolved)) - return true - } - case uint64: - if !out.OverflowUint(uint64(resolved)) { - out.SetUint(uint64(resolved)) - return true - } - case float64: - if resolved <= math.MaxUint64 && !out.OverflowUint(uint64(resolved)) { - out.SetUint(uint64(resolved)) - return true - } - } - case reflect.Bool: - switch resolved := resolved.(type) { - case bool: - out.SetBool(resolved) - return true - } - case reflect.Float32, reflect.Float64: - switch resolved := resolved.(type) { - case int: - out.SetFloat(float64(resolved)) - return true - case int64: - out.SetFloat(float64(resolved)) - return true - case uint64: - out.SetFloat(float64(resolved)) - return true - case float64: - out.SetFloat(resolved) - return true - } - case reflect.Struct: - if resolvedv := reflect.ValueOf(resolved); out.Type() == resolvedv.Type() { - out.Set(resolvedv) - return true - } - case reflect.Ptr: - if out.Type().Elem() == reflect.TypeOf(resolved) { - // TODO DOes this make sense? When is out a Ptr except when decoding a nil value? - elem := reflect.New(out.Type().Elem()) - elem.Elem().Set(reflect.ValueOf(resolved)) - out.Set(elem) - return true - } - } - d.terror(n, tag, out) - return false -} - -func settableValueOf(i interface{}) reflect.Value { - v := reflect.ValueOf(i) - sv := reflect.New(v.Type()).Elem() - sv.Set(v) - return sv -} - -func (d *decoder) sequence(n *node, out reflect.Value) (good bool) { - l := len(n.children) - - var iface reflect.Value - switch out.Kind() { - case reflect.Slice: - out.Set(reflect.MakeSlice(out.Type(), l, l)) - case reflect.Array: - if l != out.Len() { - failf("invalid array: want %d elements but got %d", out.Len(), l) - } - case reflect.Interface: - // No type hints. Will have to use a generic sequence. - iface = out - out = settableValueOf(make([]interface{}, l)) - default: - d.terror(n, yaml_SEQ_TAG, out) - return false - } - et := out.Type().Elem() - - j := 0 - for i := 0; i < l; i++ { - e := reflect.New(et).Elem() - if ok := d.unmarshal(n.children[i], e); ok { - out.Index(j).Set(e) - j++ - } - } - if out.Kind() != reflect.Array { - out.Set(out.Slice(0, j)) - } - if iface.IsValid() { - iface.Set(out) - } - return true -} - -func (d *decoder) mapping(n *node, out reflect.Value) (good bool) { - switch out.Kind() { - case reflect.Struct: - return d.mappingStruct(n, out) - case reflect.Slice: - return d.mappingSlice(n, out) - case reflect.Map: - // okay - case reflect.Interface: - if d.mapType.Kind() == reflect.Map { - iface := out - out = reflect.MakeMap(d.mapType) - iface.Set(out) - } else { - slicev := reflect.New(d.mapType).Elem() - if !d.mappingSlice(n, slicev) { - return false - } - out.Set(slicev) - return true - } - default: - d.terror(n, yaml_MAP_TAG, out) - return false - } - outt := out.Type() - kt := outt.Key() - et := outt.Elem() - - mapType := d.mapType - if outt.Key() == ifaceType && outt.Elem() == ifaceType { - d.mapType = outt - } - - if out.IsNil() { - out.Set(reflect.MakeMap(outt)) - } - l := len(n.children) - for i := 0; i < l; i += 2 { - if isMerge(n.children[i]) { - d.merge(n.children[i+1], out) - continue - } - k := reflect.New(kt).Elem() - if d.unmarshal(n.children[i], k) { - kkind := k.Kind() - if kkind == reflect.Interface { - kkind = k.Elem().Kind() - } - if kkind == reflect.Map || kkind == reflect.Slice { - failf("invalid map key: %#v", k.Interface()) - } - e := reflect.New(et).Elem() - if d.unmarshal(n.children[i+1], e) { - d.setMapIndex(n.children[i+1], out, k, e) - } - } - } - d.mapType = mapType - return true -} - -func (d *decoder) setMapIndex(n *node, out, k, v reflect.Value) { - if d.strict && out.MapIndex(k) != zeroValue { - d.terrors = append(d.terrors, fmt.Sprintf("line %d: key %#v already set in map", n.line+1, k.Interface())) - return - } - out.SetMapIndex(k, v) -} - -func (d *decoder) mappingSlice(n *node, out reflect.Value) (good bool) { - outt := out.Type() - if outt.Elem() != mapItemType { - d.terror(n, yaml_MAP_TAG, out) - return false - } - - mapType := d.mapType - d.mapType = outt - - var slice []MapItem - var l = len(n.children) - for i := 0; i < l; i += 2 { - if isMerge(n.children[i]) { - d.merge(n.children[i+1], out) - continue - } - item := MapItem{} - k := reflect.ValueOf(&item.Key).Elem() - if d.unmarshal(n.children[i], k) { - v := reflect.ValueOf(&item.Value).Elem() - if d.unmarshal(n.children[i+1], v) { - slice = append(slice, item) - } - } - } - out.Set(reflect.ValueOf(slice)) - d.mapType = mapType - return true -} - -func (d *decoder) mappingStruct(n *node, out reflect.Value) (good bool) { - sinfo, err := getStructInfo(out.Type()) - if err != nil { - panic(err) - } - name := settableValueOf("") - l := len(n.children) - - var inlineMap reflect.Value - var elemType reflect.Type - if sinfo.InlineMap != -1 { - inlineMap = out.Field(sinfo.InlineMap) - inlineMap.Set(reflect.New(inlineMap.Type()).Elem()) - elemType = inlineMap.Type().Elem() - } - - var doneFields []bool - if d.strict { - doneFields = make([]bool, len(sinfo.FieldsList)) - } - for i := 0; i < l; i += 2 { - ni := n.children[i] - if isMerge(ni) { - d.merge(n.children[i+1], out) - continue - } - if !d.unmarshal(ni, name) { - continue - } - if info, ok := sinfo.FieldsMap[name.String()]; ok { - if d.strict { - if doneFields[info.Id] { - d.terrors = append(d.terrors, fmt.Sprintf("line %d: field %s already set in type %s", ni.line+1, name.String(), out.Type())) - continue - } - doneFields[info.Id] = true - } - var field reflect.Value - if info.Inline == nil { - field = out.Field(info.Num) - } else { - field = out.FieldByIndex(info.Inline) - } - d.unmarshal(n.children[i+1], field) - } else if sinfo.InlineMap != -1 { - if inlineMap.IsNil() { - inlineMap.Set(reflect.MakeMap(inlineMap.Type())) - } - value := reflect.New(elemType).Elem() - d.unmarshal(n.children[i+1], value) - d.setMapIndex(n.children[i+1], inlineMap, name, value) - } else if d.strict { - d.terrors = append(d.terrors, fmt.Sprintf("line %d: field %s not found in type %s", ni.line+1, name.String(), out.Type())) - } - } - return true -} - -func failWantMap() { - failf("map merge requires map or sequence of maps as the value") -} - -func (d *decoder) merge(n *node, out reflect.Value) { - switch n.kind { - case mappingNode: - d.unmarshal(n, out) - case aliasNode: - if n.alias != nil && n.alias.kind != mappingNode { - failWantMap() - } - d.unmarshal(n, out) - case sequenceNode: - // Step backwards as earlier nodes take precedence. - for i := len(n.children) - 1; i >= 0; i-- { - ni := n.children[i] - if ni.kind == aliasNode { - if ni.alias != nil && ni.alias.kind != mappingNode { - failWantMap() - } - } else if ni.kind != mappingNode { - failWantMap() - } - d.unmarshal(ni, out) - } - default: - failWantMap() - } -} - -func isMerge(n *node) bool { - return n.kind == scalarNode && n.value == "<<" && (n.implicit == true || n.tag == yaml_MERGE_TAG) -} diff --git a/vendor/gopkg.in/yaml.v2/emitterc.go b/vendor/gopkg.in/yaml.v2/emitterc.go deleted file mode 100644 index a1c2cc5262..0000000000 --- a/vendor/gopkg.in/yaml.v2/emitterc.go +++ /dev/null @@ -1,1685 +0,0 @@ -package yaml - -import ( - "bytes" - "fmt" -) - -// Flush the buffer if needed. -func flush(emitter *yaml_emitter_t) bool { - if emitter.buffer_pos+5 >= len(emitter.buffer) { - return yaml_emitter_flush(emitter) - } - return true -} - -// Put a character to the output buffer. -func put(emitter *yaml_emitter_t, value byte) bool { - if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) { - return false - } - emitter.buffer[emitter.buffer_pos] = value - emitter.buffer_pos++ - emitter.column++ - return true -} - -// Put a line break to the output buffer. -func put_break(emitter *yaml_emitter_t) bool { - if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) { - return false - } - switch emitter.line_break { - case yaml_CR_BREAK: - emitter.buffer[emitter.buffer_pos] = '\r' - emitter.buffer_pos += 1 - case yaml_LN_BREAK: - emitter.buffer[emitter.buffer_pos] = '\n' - emitter.buffer_pos += 1 - case yaml_CRLN_BREAK: - emitter.buffer[emitter.buffer_pos+0] = '\r' - emitter.buffer[emitter.buffer_pos+1] = '\n' - emitter.buffer_pos += 2 - default: - panic("unknown line break setting") - } - emitter.column = 0 - emitter.line++ - return true -} - -// Copy a character from a string into buffer. -func write(emitter *yaml_emitter_t, s []byte, i *int) bool { - if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) { - return false - } - p := emitter.buffer_pos - w := width(s[*i]) - switch w { - case 4: - emitter.buffer[p+3] = s[*i+3] - fallthrough - case 3: - emitter.buffer[p+2] = s[*i+2] - fallthrough - case 2: - emitter.buffer[p+1] = s[*i+1] - fallthrough - case 1: - emitter.buffer[p+0] = s[*i+0] - default: - panic("unknown character width") - } - emitter.column++ - emitter.buffer_pos += w - *i += w - return true -} - -// Write a whole string into buffer. -func write_all(emitter *yaml_emitter_t, s []byte) bool { - for i := 0; i < len(s); { - if !write(emitter, s, &i) { - return false - } - } - return true -} - -// Copy a line break character from a string into buffer. -func write_break(emitter *yaml_emitter_t, s []byte, i *int) bool { - if s[*i] == '\n' { - if !put_break(emitter) { - return false - } - *i++ - } else { - if !write(emitter, s, i) { - return false - } - emitter.column = 0 - emitter.line++ - } - return true -} - -// Set an emitter error and return false. -func yaml_emitter_set_emitter_error(emitter *yaml_emitter_t, problem string) bool { - emitter.error = yaml_EMITTER_ERROR - emitter.problem = problem - return false -} - -// Emit an event. -func yaml_emitter_emit(emitter *yaml_emitter_t, event *yaml_event_t) bool { - emitter.events = append(emitter.events, *event) - for !yaml_emitter_need_more_events(emitter) { - event := &emitter.events[emitter.events_head] - if !yaml_emitter_analyze_event(emitter, event) { - return false - } - if !yaml_emitter_state_machine(emitter, event) { - return false - } - yaml_event_delete(event) - emitter.events_head++ - } - return true -} - -// Check if we need to accumulate more events before emitting. -// -// We accumulate extra -// - 1 event for DOCUMENT-START -// - 2 events for SEQUENCE-START -// - 3 events for MAPPING-START -// -func yaml_emitter_need_more_events(emitter *yaml_emitter_t) bool { - if emitter.events_head == len(emitter.events) { - return true - } - var accumulate int - switch emitter.events[emitter.events_head].typ { - case yaml_DOCUMENT_START_EVENT: - accumulate = 1 - break - case yaml_SEQUENCE_START_EVENT: - accumulate = 2 - break - case yaml_MAPPING_START_EVENT: - accumulate = 3 - break - default: - return false - } - if len(emitter.events)-emitter.events_head > accumulate { - return false - } - var level int - for i := emitter.events_head; i < len(emitter.events); i++ { - switch emitter.events[i].typ { - case yaml_STREAM_START_EVENT, yaml_DOCUMENT_START_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT: - level++ - case yaml_STREAM_END_EVENT, yaml_DOCUMENT_END_EVENT, yaml_SEQUENCE_END_EVENT, yaml_MAPPING_END_EVENT: - level-- - } - if level == 0 { - return false - } - } - return true -} - -// Append a directive to the directives stack. -func yaml_emitter_append_tag_directive(emitter *yaml_emitter_t, value *yaml_tag_directive_t, allow_duplicates bool) bool { - for i := 0; i < len(emitter.tag_directives); i++ { - if bytes.Equal(value.handle, emitter.tag_directives[i].handle) { - if allow_duplicates { - return true - } - return yaml_emitter_set_emitter_error(emitter, "duplicate %TAG directive") - } - } - - // [Go] Do we actually need to copy this given garbage collection - // and the lack of deallocating destructors? - tag_copy := yaml_tag_directive_t{ - handle: make([]byte, len(value.handle)), - prefix: make([]byte, len(value.prefix)), - } - copy(tag_copy.handle, value.handle) - copy(tag_copy.prefix, value.prefix) - emitter.tag_directives = append(emitter.tag_directives, tag_copy) - return true -} - -// Increase the indentation level. -func yaml_emitter_increase_indent(emitter *yaml_emitter_t, flow, indentless bool) bool { - emitter.indents = append(emitter.indents, emitter.indent) - if emitter.indent < 0 { - if flow { - emitter.indent = emitter.best_indent - } else { - emitter.indent = 0 - } - } else if !indentless { - emitter.indent += emitter.best_indent - } - return true -} - -// State dispatcher. -func yaml_emitter_state_machine(emitter *yaml_emitter_t, event *yaml_event_t) bool { - switch emitter.state { - default: - case yaml_EMIT_STREAM_START_STATE: - return yaml_emitter_emit_stream_start(emitter, event) - - case yaml_EMIT_FIRST_DOCUMENT_START_STATE: - return yaml_emitter_emit_document_start(emitter, event, true) - - case yaml_EMIT_DOCUMENT_START_STATE: - return yaml_emitter_emit_document_start(emitter, event, false) - - case yaml_EMIT_DOCUMENT_CONTENT_STATE: - return yaml_emitter_emit_document_content(emitter, event) - - case yaml_EMIT_DOCUMENT_END_STATE: - return yaml_emitter_emit_document_end(emitter, event) - - case yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE: - return yaml_emitter_emit_flow_sequence_item(emitter, event, true) - - case yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE: - return yaml_emitter_emit_flow_sequence_item(emitter, event, false) - - case yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE: - return yaml_emitter_emit_flow_mapping_key(emitter, event, true) - - case yaml_EMIT_FLOW_MAPPING_KEY_STATE: - return yaml_emitter_emit_flow_mapping_key(emitter, event, false) - - case yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE: - return yaml_emitter_emit_flow_mapping_value(emitter, event, true) - - case yaml_EMIT_FLOW_MAPPING_VALUE_STATE: - return yaml_emitter_emit_flow_mapping_value(emitter, event, false) - - case yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE: - return yaml_emitter_emit_block_sequence_item(emitter, event, true) - - case yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE: - return yaml_emitter_emit_block_sequence_item(emitter, event, false) - - case yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE: - return yaml_emitter_emit_block_mapping_key(emitter, event, true) - - case yaml_EMIT_BLOCK_MAPPING_KEY_STATE: - return yaml_emitter_emit_block_mapping_key(emitter, event, false) - - case yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE: - return yaml_emitter_emit_block_mapping_value(emitter, event, true) - - case yaml_EMIT_BLOCK_MAPPING_VALUE_STATE: - return yaml_emitter_emit_block_mapping_value(emitter, event, false) - - case yaml_EMIT_END_STATE: - return yaml_emitter_set_emitter_error(emitter, "expected nothing after STREAM-END") - } - panic("invalid emitter state") -} - -// Expect STREAM-START. -func yaml_emitter_emit_stream_start(emitter *yaml_emitter_t, event *yaml_event_t) bool { - if event.typ != yaml_STREAM_START_EVENT { - return yaml_emitter_set_emitter_error(emitter, "expected STREAM-START") - } - if emitter.encoding == yaml_ANY_ENCODING { - emitter.encoding = event.encoding - if emitter.encoding == yaml_ANY_ENCODING { - emitter.encoding = yaml_UTF8_ENCODING - } - } - if emitter.best_indent < 2 || emitter.best_indent > 9 { - emitter.best_indent = 2 - } - if emitter.best_width >= 0 && emitter.best_width <= emitter.best_indent*2 { - emitter.best_width = 80 - } - if emitter.best_width < 0 { - emitter.best_width = 1<<31 - 1 - } - if emitter.line_break == yaml_ANY_BREAK { - emitter.line_break = yaml_LN_BREAK - } - - emitter.indent = -1 - emitter.line = 0 - emitter.column = 0 - emitter.whitespace = true - emitter.indention = true - - if emitter.encoding != yaml_UTF8_ENCODING { - if !yaml_emitter_write_bom(emitter) { - return false - } - } - emitter.state = yaml_EMIT_FIRST_DOCUMENT_START_STATE - return true -} - -// Expect DOCUMENT-START or STREAM-END. -func yaml_emitter_emit_document_start(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool { - - if event.typ == yaml_DOCUMENT_START_EVENT { - - if event.version_directive != nil { - if !yaml_emitter_analyze_version_directive(emitter, event.version_directive) { - return false - } - } - - for i := 0; i < len(event.tag_directives); i++ { - tag_directive := &event.tag_directives[i] - if !yaml_emitter_analyze_tag_directive(emitter, tag_directive) { - return false - } - if !yaml_emitter_append_tag_directive(emitter, tag_directive, false) { - return false - } - } - - for i := 0; i < len(default_tag_directives); i++ { - tag_directive := &default_tag_directives[i] - if !yaml_emitter_append_tag_directive(emitter, tag_directive, true) { - return false - } - } - - implicit := event.implicit - if !first || emitter.canonical { - implicit = false - } - - if emitter.open_ended && (event.version_directive != nil || len(event.tag_directives) > 0) { - if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) { - return false - } - if !yaml_emitter_write_indent(emitter) { - return false - } - } - - if event.version_directive != nil { - implicit = false - if !yaml_emitter_write_indicator(emitter, []byte("%YAML"), true, false, false) { - return false - } - if !yaml_emitter_write_indicator(emitter, []byte("1.1"), true, false, false) { - return false - } - if !yaml_emitter_write_indent(emitter) { - return false - } - } - - if len(event.tag_directives) > 0 { - implicit = false - for i := 0; i < len(event.tag_directives); i++ { - tag_directive := &event.tag_directives[i] - if !yaml_emitter_write_indicator(emitter, []byte("%TAG"), true, false, false) { - return false - } - if !yaml_emitter_write_tag_handle(emitter, tag_directive.handle) { - return false - } - if !yaml_emitter_write_tag_content(emitter, tag_directive.prefix, true) { - return false - } - if !yaml_emitter_write_indent(emitter) { - return false - } - } - } - - if yaml_emitter_check_empty_document(emitter) { - implicit = false - } - if !implicit { - if !yaml_emitter_write_indent(emitter) { - return false - } - if !yaml_emitter_write_indicator(emitter, []byte("---"), true, false, false) { - return false - } - if emitter.canonical { - if !yaml_emitter_write_indent(emitter) { - return false - } - } - } - - emitter.state = yaml_EMIT_DOCUMENT_CONTENT_STATE - return true - } - - if event.typ == yaml_STREAM_END_EVENT { - if emitter.open_ended { - if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) { - return false - } - if !yaml_emitter_write_indent(emitter) { - return false - } - } - if !yaml_emitter_flush(emitter) { - return false - } - emitter.state = yaml_EMIT_END_STATE - return true - } - - return yaml_emitter_set_emitter_error(emitter, "expected DOCUMENT-START or STREAM-END") -} - -// Expect the root node. -func yaml_emitter_emit_document_content(emitter *yaml_emitter_t, event *yaml_event_t) bool { - emitter.states = append(emitter.states, yaml_EMIT_DOCUMENT_END_STATE) - return yaml_emitter_emit_node(emitter, event, true, false, false, false) -} - -// Expect DOCUMENT-END. -func yaml_emitter_emit_document_end(emitter *yaml_emitter_t, event *yaml_event_t) bool { - if event.typ != yaml_DOCUMENT_END_EVENT { - return yaml_emitter_set_emitter_error(emitter, "expected DOCUMENT-END") - } - if !yaml_emitter_write_indent(emitter) { - return false - } - if !event.implicit { - // [Go] Allocate the slice elsewhere. - if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) { - return false - } - if !yaml_emitter_write_indent(emitter) { - return false - } - } - if !yaml_emitter_flush(emitter) { - return false - } - emitter.state = yaml_EMIT_DOCUMENT_START_STATE - emitter.tag_directives = emitter.tag_directives[:0] - return true -} - -// Expect a flow item node. -func yaml_emitter_emit_flow_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool { - if first { - if !yaml_emitter_write_indicator(emitter, []byte{'['}, true, true, false) { - return false - } - if !yaml_emitter_increase_indent(emitter, true, false) { - return false - } - emitter.flow_level++ - } - - if event.typ == yaml_SEQUENCE_END_EVENT { - emitter.flow_level-- - emitter.indent = emitter.indents[len(emitter.indents)-1] - emitter.indents = emitter.indents[:len(emitter.indents)-1] - if emitter.canonical && !first { - if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) { - return false - } - if !yaml_emitter_write_indent(emitter) { - return false - } - } - if !yaml_emitter_write_indicator(emitter, []byte{']'}, false, false, false) { - return false - } - emitter.state = emitter.states[len(emitter.states)-1] - emitter.states = emitter.states[:len(emitter.states)-1] - - return true - } - - if !first { - if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) { - return false - } - } - - if emitter.canonical || emitter.column > emitter.best_width { - if !yaml_emitter_write_indent(emitter) { - return false - } - } - emitter.states = append(emitter.states, yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE) - return yaml_emitter_emit_node(emitter, event, false, true, false, false) -} - -// Expect a flow key node. -func yaml_emitter_emit_flow_mapping_key(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool { - if first { - if !yaml_emitter_write_indicator(emitter, []byte{'{'}, true, true, false) { - return false - } - if !yaml_emitter_increase_indent(emitter, true, false) { - return false - } - emitter.flow_level++ - } - - if event.typ == yaml_MAPPING_END_EVENT { - emitter.flow_level-- - emitter.indent = emitter.indents[len(emitter.indents)-1] - emitter.indents = emitter.indents[:len(emitter.indents)-1] - if emitter.canonical && !first { - if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) { - return false - } - if !yaml_emitter_write_indent(emitter) { - return false - } - } - if !yaml_emitter_write_indicator(emitter, []byte{'}'}, false, false, false) { - return false - } - emitter.state = emitter.states[len(emitter.states)-1] - emitter.states = emitter.states[:len(emitter.states)-1] - return true - } - - if !first { - if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) { - return false - } - } - if emitter.canonical || emitter.column > emitter.best_width { - if !yaml_emitter_write_indent(emitter) { - return false - } - } - - if !emitter.canonical && yaml_emitter_check_simple_key(emitter) { - emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE) - return yaml_emitter_emit_node(emitter, event, false, false, true, true) - } - if !yaml_emitter_write_indicator(emitter, []byte{'?'}, true, false, false) { - return false - } - emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_VALUE_STATE) - return yaml_emitter_emit_node(emitter, event, false, false, true, false) -} - -// Expect a flow value node. -func yaml_emitter_emit_flow_mapping_value(emitter *yaml_emitter_t, event *yaml_event_t, simple bool) bool { - if simple { - if !yaml_emitter_write_indicator(emitter, []byte{':'}, false, false, false) { - return false - } - } else { - if emitter.canonical || emitter.column > emitter.best_width { - if !yaml_emitter_write_indent(emitter) { - return false - } - } - if !yaml_emitter_write_indicator(emitter, []byte{':'}, true, false, false) { - return false - } - } - emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_KEY_STATE) - return yaml_emitter_emit_node(emitter, event, false, false, true, false) -} - -// Expect a block item node. -func yaml_emitter_emit_block_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool { - if first { - if !yaml_emitter_increase_indent(emitter, false, emitter.mapping_context && !emitter.indention) { - return false - } - } - if event.typ == yaml_SEQUENCE_END_EVENT { - emitter.indent = emitter.indents[len(emitter.indents)-1] - emitter.indents = emitter.indents[:len(emitter.indents)-1] - emitter.state = emitter.states[len(emitter.states)-1] - emitter.states = emitter.states[:len(emitter.states)-1] - return true - } - if !yaml_emitter_write_indent(emitter) { - return false - } - if !yaml_emitter_write_indicator(emitter, []byte{'-'}, true, false, true) { - return false - } - emitter.states = append(emitter.states, yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE) - return yaml_emitter_emit_node(emitter, event, false, true, false, false) -} - -// Expect a block key node. -func yaml_emitter_emit_block_mapping_key(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool { - if first { - if !yaml_emitter_increase_indent(emitter, false, false) { - return false - } - } - if event.typ == yaml_MAPPING_END_EVENT { - emitter.indent = emitter.indents[len(emitter.indents)-1] - emitter.indents = emitter.indents[:len(emitter.indents)-1] - emitter.state = emitter.states[len(emitter.states)-1] - emitter.states = emitter.states[:len(emitter.states)-1] - return true - } - if !yaml_emitter_write_indent(emitter) { - return false - } - if yaml_emitter_check_simple_key(emitter) { - emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE) - return yaml_emitter_emit_node(emitter, event, false, false, true, true) - } - if !yaml_emitter_write_indicator(emitter, []byte{'?'}, true, false, true) { - return false - } - emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_VALUE_STATE) - return yaml_emitter_emit_node(emitter, event, false, false, true, false) -} - -// Expect a block value node. -func yaml_emitter_emit_block_mapping_value(emitter *yaml_emitter_t, event *yaml_event_t, simple bool) bool { - if simple { - if !yaml_emitter_write_indicator(emitter, []byte{':'}, false, false, false) { - return false - } - } else { - if !yaml_emitter_write_indent(emitter) { - return false - } - if !yaml_emitter_write_indicator(emitter, []byte{':'}, true, false, true) { - return false - } - } - emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_KEY_STATE) - return yaml_emitter_emit_node(emitter, event, false, false, true, false) -} - -// Expect a node. -func yaml_emitter_emit_node(emitter *yaml_emitter_t, event *yaml_event_t, - root bool, sequence bool, mapping bool, simple_key bool) bool { - - emitter.root_context = root - emitter.sequence_context = sequence - emitter.mapping_context = mapping - emitter.simple_key_context = simple_key - - switch event.typ { - case yaml_ALIAS_EVENT: - return yaml_emitter_emit_alias(emitter, event) - case yaml_SCALAR_EVENT: - return yaml_emitter_emit_scalar(emitter, event) - case yaml_SEQUENCE_START_EVENT: - return yaml_emitter_emit_sequence_start(emitter, event) - case yaml_MAPPING_START_EVENT: - return yaml_emitter_emit_mapping_start(emitter, event) - default: - return yaml_emitter_set_emitter_error(emitter, - fmt.Sprintf("expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS, but got %v", event.typ)) - } -} - -// Expect ALIAS. -func yaml_emitter_emit_alias(emitter *yaml_emitter_t, event *yaml_event_t) bool { - if !yaml_emitter_process_anchor(emitter) { - return false - } - emitter.state = emitter.states[len(emitter.states)-1] - emitter.states = emitter.states[:len(emitter.states)-1] - return true -} - -// Expect SCALAR. -func yaml_emitter_emit_scalar(emitter *yaml_emitter_t, event *yaml_event_t) bool { - if !yaml_emitter_select_scalar_style(emitter, event) { - return false - } - if !yaml_emitter_process_anchor(emitter) { - return false - } - if !yaml_emitter_process_tag(emitter) { - return false - } - if !yaml_emitter_increase_indent(emitter, true, false) { - return false - } - if !yaml_emitter_process_scalar(emitter) { - return false - } - emitter.indent = emitter.indents[len(emitter.indents)-1] - emitter.indents = emitter.indents[:len(emitter.indents)-1] - emitter.state = emitter.states[len(emitter.states)-1] - emitter.states = emitter.states[:len(emitter.states)-1] - return true -} - -// Expect SEQUENCE-START. -func yaml_emitter_emit_sequence_start(emitter *yaml_emitter_t, event *yaml_event_t) bool { - if !yaml_emitter_process_anchor(emitter) { - return false - } - if !yaml_emitter_process_tag(emitter) { - return false - } - if emitter.flow_level > 0 || emitter.canonical || event.sequence_style() == yaml_FLOW_SEQUENCE_STYLE || - yaml_emitter_check_empty_sequence(emitter) { - emitter.state = yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE - } else { - emitter.state = yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE - } - return true -} - -// Expect MAPPING-START. -func yaml_emitter_emit_mapping_start(emitter *yaml_emitter_t, event *yaml_event_t) bool { - if !yaml_emitter_process_anchor(emitter) { - return false - } - if !yaml_emitter_process_tag(emitter) { - return false - } - if emitter.flow_level > 0 || emitter.canonical || event.mapping_style() == yaml_FLOW_MAPPING_STYLE || - yaml_emitter_check_empty_mapping(emitter) { - emitter.state = yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE - } else { - emitter.state = yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE - } - return true -} - -// Check if the document content is an empty scalar. -func yaml_emitter_check_empty_document(emitter *yaml_emitter_t) bool { - return false // [Go] Huh? -} - -// Check if the next events represent an empty sequence. -func yaml_emitter_check_empty_sequence(emitter *yaml_emitter_t) bool { - if len(emitter.events)-emitter.events_head < 2 { - return false - } - return emitter.events[emitter.events_head].typ == yaml_SEQUENCE_START_EVENT && - emitter.events[emitter.events_head+1].typ == yaml_SEQUENCE_END_EVENT -} - -// Check if the next events represent an empty mapping. -func yaml_emitter_check_empty_mapping(emitter *yaml_emitter_t) bool { - if len(emitter.events)-emitter.events_head < 2 { - return false - } - return emitter.events[emitter.events_head].typ == yaml_MAPPING_START_EVENT && - emitter.events[emitter.events_head+1].typ == yaml_MAPPING_END_EVENT -} - -// Check if the next node can be expressed as a simple key. -func yaml_emitter_check_simple_key(emitter *yaml_emitter_t) bool { - length := 0 - switch emitter.events[emitter.events_head].typ { - case yaml_ALIAS_EVENT: - length += len(emitter.anchor_data.anchor) - case yaml_SCALAR_EVENT: - if emitter.scalar_data.multiline { - return false - } - length += len(emitter.anchor_data.anchor) + - len(emitter.tag_data.handle) + - len(emitter.tag_data.suffix) + - len(emitter.scalar_data.value) - case yaml_SEQUENCE_START_EVENT: - if !yaml_emitter_check_empty_sequence(emitter) { - return false - } - length += len(emitter.anchor_data.anchor) + - len(emitter.tag_data.handle) + - len(emitter.tag_data.suffix) - case yaml_MAPPING_START_EVENT: - if !yaml_emitter_check_empty_mapping(emitter) { - return false - } - length += len(emitter.anchor_data.anchor) + - len(emitter.tag_data.handle) + - len(emitter.tag_data.suffix) - default: - return false - } - return length <= 128 -} - -// Determine an acceptable scalar style. -func yaml_emitter_select_scalar_style(emitter *yaml_emitter_t, event *yaml_event_t) bool { - - no_tag := len(emitter.tag_data.handle) == 0 && len(emitter.tag_data.suffix) == 0 - if no_tag && !event.implicit && !event.quoted_implicit { - return yaml_emitter_set_emitter_error(emitter, "neither tag nor implicit flags are specified") - } - - style := event.scalar_style() - if style == yaml_ANY_SCALAR_STYLE { - style = yaml_PLAIN_SCALAR_STYLE - } - if emitter.canonical { - style = yaml_DOUBLE_QUOTED_SCALAR_STYLE - } - if emitter.simple_key_context && emitter.scalar_data.multiline { - style = yaml_DOUBLE_QUOTED_SCALAR_STYLE - } - - if style == yaml_PLAIN_SCALAR_STYLE { - if emitter.flow_level > 0 && !emitter.scalar_data.flow_plain_allowed || - emitter.flow_level == 0 && !emitter.scalar_data.block_plain_allowed { - style = yaml_SINGLE_QUOTED_SCALAR_STYLE - } - if len(emitter.scalar_data.value) == 0 && (emitter.flow_level > 0 || emitter.simple_key_context) { - style = yaml_SINGLE_QUOTED_SCALAR_STYLE - } - if no_tag && !event.implicit { - style = yaml_SINGLE_QUOTED_SCALAR_STYLE - } - } - if style == yaml_SINGLE_QUOTED_SCALAR_STYLE { - if !emitter.scalar_data.single_quoted_allowed { - style = yaml_DOUBLE_QUOTED_SCALAR_STYLE - } - } - if style == yaml_LITERAL_SCALAR_STYLE || style == yaml_FOLDED_SCALAR_STYLE { - if !emitter.scalar_data.block_allowed || emitter.flow_level > 0 || emitter.simple_key_context { - style = yaml_DOUBLE_QUOTED_SCALAR_STYLE - } - } - - if no_tag && !event.quoted_implicit && style != yaml_PLAIN_SCALAR_STYLE { - emitter.tag_data.handle = []byte{'!'} - } - emitter.scalar_data.style = style - return true -} - -// Write an anchor. -func yaml_emitter_process_anchor(emitter *yaml_emitter_t) bool { - if emitter.anchor_data.anchor == nil { - return true - } - c := []byte{'&'} - if emitter.anchor_data.alias { - c[0] = '*' - } - if !yaml_emitter_write_indicator(emitter, c, true, false, false) { - return false - } - return yaml_emitter_write_anchor(emitter, emitter.anchor_data.anchor) -} - -// Write a tag. -func yaml_emitter_process_tag(emitter *yaml_emitter_t) bool { - if len(emitter.tag_data.handle) == 0 && len(emitter.tag_data.suffix) == 0 { - return true - } - if len(emitter.tag_data.handle) > 0 { - if !yaml_emitter_write_tag_handle(emitter, emitter.tag_data.handle) { - return false - } - if len(emitter.tag_data.suffix) > 0 { - if !yaml_emitter_write_tag_content(emitter, emitter.tag_data.suffix, false) { - return false - } - } - } else { - // [Go] Allocate these slices elsewhere. - if !yaml_emitter_write_indicator(emitter, []byte("!<"), true, false, false) { - return false - } - if !yaml_emitter_write_tag_content(emitter, emitter.tag_data.suffix, false) { - return false - } - if !yaml_emitter_write_indicator(emitter, []byte{'>'}, false, false, false) { - return false - } - } - return true -} - -// Write a scalar. -func yaml_emitter_process_scalar(emitter *yaml_emitter_t) bool { - switch emitter.scalar_data.style { - case yaml_PLAIN_SCALAR_STYLE: - return yaml_emitter_write_plain_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context) - - case yaml_SINGLE_QUOTED_SCALAR_STYLE: - return yaml_emitter_write_single_quoted_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context) - - case yaml_DOUBLE_QUOTED_SCALAR_STYLE: - return yaml_emitter_write_double_quoted_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context) - - case yaml_LITERAL_SCALAR_STYLE: - return yaml_emitter_write_literal_scalar(emitter, emitter.scalar_data.value) - - case yaml_FOLDED_SCALAR_STYLE: - return yaml_emitter_write_folded_scalar(emitter, emitter.scalar_data.value) - } - panic("unknown scalar style") -} - -// Check if a %YAML directive is valid. -func yaml_emitter_analyze_version_directive(emitter *yaml_emitter_t, version_directive *yaml_version_directive_t) bool { - if version_directive.major != 1 || version_directive.minor != 1 { - return yaml_emitter_set_emitter_error(emitter, "incompatible %YAML directive") - } - return true -} - -// Check if a %TAG directive is valid. -func yaml_emitter_analyze_tag_directive(emitter *yaml_emitter_t, tag_directive *yaml_tag_directive_t) bool { - handle := tag_directive.handle - prefix := tag_directive.prefix - if len(handle) == 0 { - return yaml_emitter_set_emitter_error(emitter, "tag handle must not be empty") - } - if handle[0] != '!' { - return yaml_emitter_set_emitter_error(emitter, "tag handle must start with '!'") - } - if handle[len(handle)-1] != '!' { - return yaml_emitter_set_emitter_error(emitter, "tag handle must end with '!'") - } - for i := 1; i < len(handle)-1; i += width(handle[i]) { - if !is_alpha(handle, i) { - return yaml_emitter_set_emitter_error(emitter, "tag handle must contain alphanumerical characters only") - } - } - if len(prefix) == 0 { - return yaml_emitter_set_emitter_error(emitter, "tag prefix must not be empty") - } - return true -} - -// Check if an anchor is valid. -func yaml_emitter_analyze_anchor(emitter *yaml_emitter_t, anchor []byte, alias bool) bool { - if len(anchor) == 0 { - problem := "anchor value must not be empty" - if alias { - problem = "alias value must not be empty" - } - return yaml_emitter_set_emitter_error(emitter, problem) - } - for i := 0; i < len(anchor); i += width(anchor[i]) { - if !is_alpha(anchor, i) { - problem := "anchor value must contain alphanumerical characters only" - if alias { - problem = "alias value must contain alphanumerical characters only" - } - return yaml_emitter_set_emitter_error(emitter, problem) - } - } - emitter.anchor_data.anchor = anchor - emitter.anchor_data.alias = alias - return true -} - -// Check if a tag is valid. -func yaml_emitter_analyze_tag(emitter *yaml_emitter_t, tag []byte) bool { - if len(tag) == 0 { - return yaml_emitter_set_emitter_error(emitter, "tag value must not be empty") - } - for i := 0; i < len(emitter.tag_directives); i++ { - tag_directive := &emitter.tag_directives[i] - if bytes.HasPrefix(tag, tag_directive.prefix) { - emitter.tag_data.handle = tag_directive.handle - emitter.tag_data.suffix = tag[len(tag_directive.prefix):] - return true - } - } - emitter.tag_data.suffix = tag - return true -} - -// Check if a scalar is valid. -func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool { - var ( - block_indicators = false - flow_indicators = false - line_breaks = false - special_characters = false - - leading_space = false - leading_break = false - trailing_space = false - trailing_break = false - break_space = false - space_break = false - - preceded_by_whitespace = false - followed_by_whitespace = false - previous_space = false - previous_break = false - ) - - emitter.scalar_data.value = value - - if len(value) == 0 { - emitter.scalar_data.multiline = false - emitter.scalar_data.flow_plain_allowed = false - emitter.scalar_data.block_plain_allowed = true - emitter.scalar_data.single_quoted_allowed = true - emitter.scalar_data.block_allowed = false - return true - } - - if len(value) >= 3 && ((value[0] == '-' && value[1] == '-' && value[2] == '-') || (value[0] == '.' && value[1] == '.' && value[2] == '.')) { - block_indicators = true - flow_indicators = true - } - - preceded_by_whitespace = true - for i, w := 0, 0; i < len(value); i += w { - w = width(value[i]) - followed_by_whitespace = i+w >= len(value) || is_blank(value, i+w) - - if i == 0 { - switch value[i] { - case '#', ',', '[', ']', '{', '}', '&', '*', '!', '|', '>', '\'', '"', '%', '@', '`': - flow_indicators = true - block_indicators = true - case '?', ':': - flow_indicators = true - if followed_by_whitespace { - block_indicators = true - } - case '-': - if followed_by_whitespace { - flow_indicators = true - block_indicators = true - } - } - } else { - switch value[i] { - case ',', '?', '[', ']', '{', '}': - flow_indicators = true - case ':': - flow_indicators = true - if followed_by_whitespace { - block_indicators = true - } - case '#': - if preceded_by_whitespace { - flow_indicators = true - block_indicators = true - } - } - } - - if !is_printable(value, i) || !is_ascii(value, i) && !emitter.unicode { - special_characters = true - } - if is_space(value, i) { - if i == 0 { - leading_space = true - } - if i+width(value[i]) == len(value) { - trailing_space = true - } - if previous_break { - break_space = true - } - previous_space = true - previous_break = false - } else if is_break(value, i) { - line_breaks = true - if i == 0 { - leading_break = true - } - if i+width(value[i]) == len(value) { - trailing_break = true - } - if previous_space { - space_break = true - } - previous_space = false - previous_break = true - } else { - previous_space = false - previous_break = false - } - - // [Go]: Why 'z'? Couldn't be the end of the string as that's the loop condition. - preceded_by_whitespace = is_blankz(value, i) - } - - emitter.scalar_data.multiline = line_breaks - emitter.scalar_data.flow_plain_allowed = true - emitter.scalar_data.block_plain_allowed = true - emitter.scalar_data.single_quoted_allowed = true - emitter.scalar_data.block_allowed = true - - if leading_space || leading_break || trailing_space || trailing_break { - emitter.scalar_data.flow_plain_allowed = false - emitter.scalar_data.block_plain_allowed = false - } - if trailing_space { - emitter.scalar_data.block_allowed = false - } - if break_space { - emitter.scalar_data.flow_plain_allowed = false - emitter.scalar_data.block_plain_allowed = false - emitter.scalar_data.single_quoted_allowed = false - } - if space_break || special_characters { - emitter.scalar_data.flow_plain_allowed = false - emitter.scalar_data.block_plain_allowed = false - emitter.scalar_data.single_quoted_allowed = false - emitter.scalar_data.block_allowed = false - } - if line_breaks { - emitter.scalar_data.flow_plain_allowed = false - emitter.scalar_data.block_plain_allowed = false - } - if flow_indicators { - emitter.scalar_data.flow_plain_allowed = false - } - if block_indicators { - emitter.scalar_data.block_plain_allowed = false - } - return true -} - -// Check if the event data is valid. -func yaml_emitter_analyze_event(emitter *yaml_emitter_t, event *yaml_event_t) bool { - - emitter.anchor_data.anchor = nil - emitter.tag_data.handle = nil - emitter.tag_data.suffix = nil - emitter.scalar_data.value = nil - - switch event.typ { - case yaml_ALIAS_EVENT: - if !yaml_emitter_analyze_anchor(emitter, event.anchor, true) { - return false - } - - case yaml_SCALAR_EVENT: - if len(event.anchor) > 0 { - if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) { - return false - } - } - if len(event.tag) > 0 && (emitter.canonical || (!event.implicit && !event.quoted_implicit)) { - if !yaml_emitter_analyze_tag(emitter, event.tag) { - return false - } - } - if !yaml_emitter_analyze_scalar(emitter, event.value) { - return false - } - - case yaml_SEQUENCE_START_EVENT: - if len(event.anchor) > 0 { - if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) { - return false - } - } - if len(event.tag) > 0 && (emitter.canonical || !event.implicit) { - if !yaml_emitter_analyze_tag(emitter, event.tag) { - return false - } - } - - case yaml_MAPPING_START_EVENT: - if len(event.anchor) > 0 { - if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) { - return false - } - } - if len(event.tag) > 0 && (emitter.canonical || !event.implicit) { - if !yaml_emitter_analyze_tag(emitter, event.tag) { - return false - } - } - } - return true -} - -// Write the BOM character. -func yaml_emitter_write_bom(emitter *yaml_emitter_t) bool { - if !flush(emitter) { - return false - } - pos := emitter.buffer_pos - emitter.buffer[pos+0] = '\xEF' - emitter.buffer[pos+1] = '\xBB' - emitter.buffer[pos+2] = '\xBF' - emitter.buffer_pos += 3 - return true -} - -func yaml_emitter_write_indent(emitter *yaml_emitter_t) bool { - indent := emitter.indent - if indent < 0 { - indent = 0 - } - if !emitter.indention || emitter.column > indent || (emitter.column == indent && !emitter.whitespace) { - if !put_break(emitter) { - return false - } - } - for emitter.column < indent { - if !put(emitter, ' ') { - return false - } - } - emitter.whitespace = true - emitter.indention = true - return true -} - -func yaml_emitter_write_indicator(emitter *yaml_emitter_t, indicator []byte, need_whitespace, is_whitespace, is_indention bool) bool { - if need_whitespace && !emitter.whitespace { - if !put(emitter, ' ') { - return false - } - } - if !write_all(emitter, indicator) { - return false - } - emitter.whitespace = is_whitespace - emitter.indention = (emitter.indention && is_indention) - emitter.open_ended = false - return true -} - -func yaml_emitter_write_anchor(emitter *yaml_emitter_t, value []byte) bool { - if !write_all(emitter, value) { - return false - } - emitter.whitespace = false - emitter.indention = false - return true -} - -func yaml_emitter_write_tag_handle(emitter *yaml_emitter_t, value []byte) bool { - if !emitter.whitespace { - if !put(emitter, ' ') { - return false - } - } - if !write_all(emitter, value) { - return false - } - emitter.whitespace = false - emitter.indention = false - return true -} - -func yaml_emitter_write_tag_content(emitter *yaml_emitter_t, value []byte, need_whitespace bool) bool { - if need_whitespace && !emitter.whitespace { - if !put(emitter, ' ') { - return false - } - } - for i := 0; i < len(value); { - var must_write bool - switch value[i] { - case ';', '/', '?', ':', '@', '&', '=', '+', '$', ',', '_', '.', '~', '*', '\'', '(', ')', '[', ']': - must_write = true - default: - must_write = is_alpha(value, i) - } - if must_write { - if !write(emitter, value, &i) { - return false - } - } else { - w := width(value[i]) - for k := 0; k < w; k++ { - octet := value[i] - i++ - if !put(emitter, '%') { - return false - } - - c := octet >> 4 - if c < 10 { - c += '0' - } else { - c += 'A' - 10 - } - if !put(emitter, c) { - return false - } - - c = octet & 0x0f - if c < 10 { - c += '0' - } else { - c += 'A' - 10 - } - if !put(emitter, c) { - return false - } - } - } - } - emitter.whitespace = false - emitter.indention = false - return true -} - -func yaml_emitter_write_plain_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool { - if !emitter.whitespace { - if !put(emitter, ' ') { - return false - } - } - - spaces := false - breaks := false - for i := 0; i < len(value); { - if is_space(value, i) { - if allow_breaks && !spaces && emitter.column > emitter.best_width && !is_space(value, i+1) { - if !yaml_emitter_write_indent(emitter) { - return false - } - i += width(value[i]) - } else { - if !write(emitter, value, &i) { - return false - } - } - spaces = true - } else if is_break(value, i) { - if !breaks && value[i] == '\n' { - if !put_break(emitter) { - return false - } - } - if !write_break(emitter, value, &i) { - return false - } - emitter.indention = true - breaks = true - } else { - if breaks { - if !yaml_emitter_write_indent(emitter) { - return false - } - } - if !write(emitter, value, &i) { - return false - } - emitter.indention = false - spaces = false - breaks = false - } - } - - emitter.whitespace = false - emitter.indention = false - if emitter.root_context { - emitter.open_ended = true - } - - return true -} - -func yaml_emitter_write_single_quoted_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool { - - if !yaml_emitter_write_indicator(emitter, []byte{'\''}, true, false, false) { - return false - } - - spaces := false - breaks := false - for i := 0; i < len(value); { - if is_space(value, i) { - if allow_breaks && !spaces && emitter.column > emitter.best_width && i > 0 && i < len(value)-1 && !is_space(value, i+1) { - if !yaml_emitter_write_indent(emitter) { - return false - } - i += width(value[i]) - } else { - if !write(emitter, value, &i) { - return false - } - } - spaces = true - } else if is_break(value, i) { - if !breaks && value[i] == '\n' { - if !put_break(emitter) { - return false - } - } - if !write_break(emitter, value, &i) { - return false - } - emitter.indention = true - breaks = true - } else { - if breaks { - if !yaml_emitter_write_indent(emitter) { - return false - } - } - if value[i] == '\'' { - if !put(emitter, '\'') { - return false - } - } - if !write(emitter, value, &i) { - return false - } - emitter.indention = false - spaces = false - breaks = false - } - } - if !yaml_emitter_write_indicator(emitter, []byte{'\''}, false, false, false) { - return false - } - emitter.whitespace = false - emitter.indention = false - return true -} - -func yaml_emitter_write_double_quoted_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool { - spaces := false - if !yaml_emitter_write_indicator(emitter, []byte{'"'}, true, false, false) { - return false - } - - for i := 0; i < len(value); { - if !is_printable(value, i) || (!emitter.unicode && !is_ascii(value, i)) || - is_bom(value, i) || is_break(value, i) || - value[i] == '"' || value[i] == '\\' { - - octet := value[i] - - var w int - var v rune - switch { - case octet&0x80 == 0x00: - w, v = 1, rune(octet&0x7F) - case octet&0xE0 == 0xC0: - w, v = 2, rune(octet&0x1F) - case octet&0xF0 == 0xE0: - w, v = 3, rune(octet&0x0F) - case octet&0xF8 == 0xF0: - w, v = 4, rune(octet&0x07) - } - for k := 1; k < w; k++ { - octet = value[i+k] - v = (v << 6) + (rune(octet) & 0x3F) - } - i += w - - if !put(emitter, '\\') { - return false - } - - var ok bool - switch v { - case 0x00: - ok = put(emitter, '0') - case 0x07: - ok = put(emitter, 'a') - case 0x08: - ok = put(emitter, 'b') - case 0x09: - ok = put(emitter, 't') - case 0x0A: - ok = put(emitter, 'n') - case 0x0b: - ok = put(emitter, 'v') - case 0x0c: - ok = put(emitter, 'f') - case 0x0d: - ok = put(emitter, 'r') - case 0x1b: - ok = put(emitter, 'e') - case 0x22: - ok = put(emitter, '"') - case 0x5c: - ok = put(emitter, '\\') - case 0x85: - ok = put(emitter, 'N') - case 0xA0: - ok = put(emitter, '_') - case 0x2028: - ok = put(emitter, 'L') - case 0x2029: - ok = put(emitter, 'P') - default: - if v <= 0xFF { - ok = put(emitter, 'x') - w = 2 - } else if v <= 0xFFFF { - ok = put(emitter, 'u') - w = 4 - } else { - ok = put(emitter, 'U') - w = 8 - } - for k := (w - 1) * 4; ok && k >= 0; k -= 4 { - digit := byte((v >> uint(k)) & 0x0F) - if digit < 10 { - ok = put(emitter, digit+'0') - } else { - ok = put(emitter, digit+'A'-10) - } - } - } - if !ok { - return false - } - spaces = false - } else if is_space(value, i) { - if allow_breaks && !spaces && emitter.column > emitter.best_width && i > 0 && i < len(value)-1 { - if !yaml_emitter_write_indent(emitter) { - return false - } - if is_space(value, i+1) { - if !put(emitter, '\\') { - return false - } - } - i += width(value[i]) - } else if !write(emitter, value, &i) { - return false - } - spaces = true - } else { - if !write(emitter, value, &i) { - return false - } - spaces = false - } - } - if !yaml_emitter_write_indicator(emitter, []byte{'"'}, false, false, false) { - return false - } - emitter.whitespace = false - emitter.indention = false - return true -} - -func yaml_emitter_write_block_scalar_hints(emitter *yaml_emitter_t, value []byte) bool { - if is_space(value, 0) || is_break(value, 0) { - indent_hint := []byte{'0' + byte(emitter.best_indent)} - if !yaml_emitter_write_indicator(emitter, indent_hint, false, false, false) { - return false - } - } - - emitter.open_ended = false - - var chomp_hint [1]byte - if len(value) == 0 { - chomp_hint[0] = '-' - } else { - i := len(value) - 1 - for value[i]&0xC0 == 0x80 { - i-- - } - if !is_break(value, i) { - chomp_hint[0] = '-' - } else if i == 0 { - chomp_hint[0] = '+' - emitter.open_ended = true - } else { - i-- - for value[i]&0xC0 == 0x80 { - i-- - } - if is_break(value, i) { - chomp_hint[0] = '+' - emitter.open_ended = true - } - } - } - if chomp_hint[0] != 0 { - if !yaml_emitter_write_indicator(emitter, chomp_hint[:], false, false, false) { - return false - } - } - return true -} - -func yaml_emitter_write_literal_scalar(emitter *yaml_emitter_t, value []byte) bool { - if !yaml_emitter_write_indicator(emitter, []byte{'|'}, true, false, false) { - return false - } - if !yaml_emitter_write_block_scalar_hints(emitter, value) { - return false - } - if !put_break(emitter) { - return false - } - emitter.indention = true - emitter.whitespace = true - breaks := true - for i := 0; i < len(value); { - if is_break(value, i) { - if !write_break(emitter, value, &i) { - return false - } - emitter.indention = true - breaks = true - } else { - if breaks { - if !yaml_emitter_write_indent(emitter) { - return false - } - } - if !write(emitter, value, &i) { - return false - } - emitter.indention = false - breaks = false - } - } - - return true -} - -func yaml_emitter_write_folded_scalar(emitter *yaml_emitter_t, value []byte) bool { - if !yaml_emitter_write_indicator(emitter, []byte{'>'}, true, false, false) { - return false - } - if !yaml_emitter_write_block_scalar_hints(emitter, value) { - return false - } - - if !put_break(emitter) { - return false - } - emitter.indention = true - emitter.whitespace = true - - breaks := true - leading_spaces := true - for i := 0; i < len(value); { - if is_break(value, i) { - if !breaks && !leading_spaces && value[i] == '\n' { - k := 0 - for is_break(value, k) { - k += width(value[k]) - } - if !is_blankz(value, k) { - if !put_break(emitter) { - return false - } - } - } - if !write_break(emitter, value, &i) { - return false - } - emitter.indention = true - breaks = true - } else { - if breaks { - if !yaml_emitter_write_indent(emitter) { - return false - } - leading_spaces = is_blank(value, i) - } - if !breaks && is_space(value, i) && !is_space(value, i+1) && emitter.column > emitter.best_width { - if !yaml_emitter_write_indent(emitter) { - return false - } - i += width(value[i]) - } else { - if !write(emitter, value, &i) { - return false - } - } - emitter.indention = false - breaks = false - } - } - return true -} diff --git a/vendor/gopkg.in/yaml.v2/encode.go b/vendor/gopkg.in/yaml.v2/encode.go deleted file mode 100644 index 0ee738e11b..0000000000 --- a/vendor/gopkg.in/yaml.v2/encode.go +++ /dev/null @@ -1,390 +0,0 @@ -package yaml - -import ( - "encoding" - "fmt" - "io" - "reflect" - "regexp" - "sort" - "strconv" - "strings" - "time" - "unicode/utf8" -) - -// jsonNumber is the interface of the encoding/json.Number datatype. -// Repeating the interface here avoids a dependency on encoding/json, and also -// supports other libraries like jsoniter, which use a similar datatype with -// the same interface. Detecting this interface is useful when dealing with -// structures containing json.Number, which is a string under the hood. The -// encoder should prefer the use of Int64(), Float64() and string(), in that -// order, when encoding this type. -type jsonNumber interface { - Float64() (float64, error) - Int64() (int64, error) - String() string -} - -type encoder struct { - emitter yaml_emitter_t - event yaml_event_t - out []byte - flow bool - // doneInit holds whether the initial stream_start_event has been - // emitted. - doneInit bool -} - -func newEncoder() *encoder { - e := &encoder{} - yaml_emitter_initialize(&e.emitter) - yaml_emitter_set_output_string(&e.emitter, &e.out) - yaml_emitter_set_unicode(&e.emitter, true) - return e -} - -func newEncoderWithWriter(w io.Writer) *encoder { - e := &encoder{} - yaml_emitter_initialize(&e.emitter) - yaml_emitter_set_output_writer(&e.emitter, w) - yaml_emitter_set_unicode(&e.emitter, true) - return e -} - -func (e *encoder) init() { - if e.doneInit { - return - } - yaml_stream_start_event_initialize(&e.event, yaml_UTF8_ENCODING) - e.emit() - e.doneInit = true -} - -func (e *encoder) finish() { - e.emitter.open_ended = false - yaml_stream_end_event_initialize(&e.event) - e.emit() -} - -func (e *encoder) destroy() { - yaml_emitter_delete(&e.emitter) -} - -func (e *encoder) emit() { - // This will internally delete the e.event value. - e.must(yaml_emitter_emit(&e.emitter, &e.event)) -} - -func (e *encoder) must(ok bool) { - if !ok { - msg := e.emitter.problem - if msg == "" { - msg = "unknown problem generating YAML content" - } - failf("%s", msg) - } -} - -func (e *encoder) marshalDoc(tag string, in reflect.Value) { - e.init() - yaml_document_start_event_initialize(&e.event, nil, nil, true) - e.emit() - e.marshal(tag, in) - yaml_document_end_event_initialize(&e.event, true) - e.emit() -} - -func (e *encoder) marshal(tag string, in reflect.Value) { - if !in.IsValid() || in.Kind() == reflect.Ptr && in.IsNil() { - e.nilv() - return - } - iface := in.Interface() - switch m := iface.(type) { - case jsonNumber: - integer, err := m.Int64() - if err == nil { - // In this case the json.Number is a valid int64 - in = reflect.ValueOf(integer) - break - } - float, err := m.Float64() - if err == nil { - // In this case the json.Number is a valid float64 - in = reflect.ValueOf(float) - break - } - // fallback case - no number could be obtained - in = reflect.ValueOf(m.String()) - case time.Time, *time.Time: - // Although time.Time implements TextMarshaler, - // we don't want to treat it as a string for YAML - // purposes because YAML has special support for - // timestamps. - case Marshaler: - v, err := m.MarshalYAML() - if err != nil { - fail(err) - } - if v == nil { - e.nilv() - return - } - in = reflect.ValueOf(v) - case encoding.TextMarshaler: - text, err := m.MarshalText() - if err != nil { - fail(err) - } - in = reflect.ValueOf(string(text)) - case nil: - e.nilv() - return - } - switch in.Kind() { - case reflect.Interface: - e.marshal(tag, in.Elem()) - case reflect.Map: - e.mapv(tag, in) - case reflect.Ptr: - if in.Type() == ptrTimeType { - e.timev(tag, in.Elem()) - } else { - e.marshal(tag, in.Elem()) - } - case reflect.Struct: - if in.Type() == timeType { - e.timev(tag, in) - } else { - e.structv(tag, in) - } - case reflect.Slice, reflect.Array: - if in.Type().Elem() == mapItemType { - e.itemsv(tag, in) - } else { - e.slicev(tag, in) - } - case reflect.String: - e.stringv(tag, in) - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - if in.Type() == durationType { - e.stringv(tag, reflect.ValueOf(iface.(time.Duration).String())) - } else { - e.intv(tag, in) - } - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - e.uintv(tag, in) - case reflect.Float32, reflect.Float64: - e.floatv(tag, in) - case reflect.Bool: - e.boolv(tag, in) - default: - panic("cannot marshal type: " + in.Type().String()) - } -} - -func (e *encoder) mapv(tag string, in reflect.Value) { - e.mappingv(tag, func() { - keys := keyList(in.MapKeys()) - sort.Sort(keys) - for _, k := range keys { - e.marshal("", k) - e.marshal("", in.MapIndex(k)) - } - }) -} - -func (e *encoder) itemsv(tag string, in reflect.Value) { - e.mappingv(tag, func() { - slice := in.Convert(reflect.TypeOf([]MapItem{})).Interface().([]MapItem) - for _, item := range slice { - e.marshal("", reflect.ValueOf(item.Key)) - e.marshal("", reflect.ValueOf(item.Value)) - } - }) -} - -func (e *encoder) structv(tag string, in reflect.Value) { - sinfo, err := getStructInfo(in.Type()) - if err != nil { - panic(err) - } - e.mappingv(tag, func() { - for _, info := range sinfo.FieldsList { - var value reflect.Value - if info.Inline == nil { - value = in.Field(info.Num) - } else { - value = in.FieldByIndex(info.Inline) - } - if info.OmitEmpty && isZero(value) { - continue - } - e.marshal("", reflect.ValueOf(info.Key)) - e.flow = info.Flow - e.marshal("", value) - } - if sinfo.InlineMap >= 0 { - m := in.Field(sinfo.InlineMap) - if m.Len() > 0 { - e.flow = false - keys := keyList(m.MapKeys()) - sort.Sort(keys) - for _, k := range keys { - if _, found := sinfo.FieldsMap[k.String()]; found { - panic(fmt.Sprintf("Can't have key %q in inlined map; conflicts with struct field", k.String())) - } - e.marshal("", k) - e.flow = false - e.marshal("", m.MapIndex(k)) - } - } - } - }) -} - -func (e *encoder) mappingv(tag string, f func()) { - implicit := tag == "" - style := yaml_BLOCK_MAPPING_STYLE - if e.flow { - e.flow = false - style = yaml_FLOW_MAPPING_STYLE - } - yaml_mapping_start_event_initialize(&e.event, nil, []byte(tag), implicit, style) - e.emit() - f() - yaml_mapping_end_event_initialize(&e.event) - e.emit() -} - -func (e *encoder) slicev(tag string, in reflect.Value) { - implicit := tag == "" - style := yaml_BLOCK_SEQUENCE_STYLE - if e.flow { - e.flow = false - style = yaml_FLOW_SEQUENCE_STYLE - } - e.must(yaml_sequence_start_event_initialize(&e.event, nil, []byte(tag), implicit, style)) - e.emit() - n := in.Len() - for i := 0; i < n; i++ { - e.marshal("", in.Index(i)) - } - e.must(yaml_sequence_end_event_initialize(&e.event)) - e.emit() -} - -// isBase60 returns whether s is in base 60 notation as defined in YAML 1.1. -// -// The base 60 float notation in YAML 1.1 is a terrible idea and is unsupported -// in YAML 1.2 and by this package, but these should be marshalled quoted for -// the time being for compatibility with other parsers. -func isBase60Float(s string) (result bool) { - // Fast path. - if s == "" { - return false - } - c := s[0] - if !(c == '+' || c == '-' || c >= '0' && c <= '9') || strings.IndexByte(s, ':') < 0 { - return false - } - // Do the full match. - return base60float.MatchString(s) -} - -// From http://yaml.org/type/float.html, except the regular expression there -// is bogus. In practice parsers do not enforce the "\.[0-9_]*" suffix. -var base60float = regexp.MustCompile(`^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+(?:\.[0-9_]*)?$`) - -func (e *encoder) stringv(tag string, in reflect.Value) { - var style yaml_scalar_style_t - s := in.String() - canUsePlain := true - switch { - case !utf8.ValidString(s): - if tag == yaml_BINARY_TAG { - failf("explicitly tagged !!binary data must be base64-encoded") - } - if tag != "" { - failf("cannot marshal invalid UTF-8 data as %s", shortTag(tag)) - } - // It can't be encoded directly as YAML so use a binary tag - // and encode it as base64. - tag = yaml_BINARY_TAG - s = encodeBase64(s) - case tag == "": - // Check to see if it would resolve to a specific - // tag when encoded unquoted. If it doesn't, - // there's no need to quote it. - rtag, _ := resolve("", s) - canUsePlain = rtag == yaml_STR_TAG && !isBase60Float(s) - } - // Note: it's possible for user code to emit invalid YAML - // if they explicitly specify a tag and a string containing - // text that's incompatible with that tag. - switch { - case strings.Contains(s, "\n"): - style = yaml_LITERAL_SCALAR_STYLE - case canUsePlain: - style = yaml_PLAIN_SCALAR_STYLE - default: - style = yaml_DOUBLE_QUOTED_SCALAR_STYLE - } - e.emitScalar(s, "", tag, style) -} - -func (e *encoder) boolv(tag string, in reflect.Value) { - var s string - if in.Bool() { - s = "true" - } else { - s = "false" - } - e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE) -} - -func (e *encoder) intv(tag string, in reflect.Value) { - s := strconv.FormatInt(in.Int(), 10) - e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE) -} - -func (e *encoder) uintv(tag string, in reflect.Value) { - s := strconv.FormatUint(in.Uint(), 10) - e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE) -} - -func (e *encoder) timev(tag string, in reflect.Value) { - t := in.Interface().(time.Time) - s := t.Format(time.RFC3339Nano) - e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE) -} - -func (e *encoder) floatv(tag string, in reflect.Value) { - // Issue #352: When formatting, use the precision of the underlying value - precision := 64 - if in.Kind() == reflect.Float32 { - precision = 32 - } - - s := strconv.FormatFloat(in.Float(), 'g', -1, precision) - switch s { - case "+Inf": - s = ".inf" - case "-Inf": - s = "-.inf" - case "NaN": - s = ".nan" - } - e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE) -} - -func (e *encoder) nilv() { - e.emitScalar("null", "", "", yaml_PLAIN_SCALAR_STYLE) -} - -func (e *encoder) emitScalar(value, anchor, tag string, style yaml_scalar_style_t) { - implicit := tag == "" - e.must(yaml_scalar_event_initialize(&e.event, []byte(anchor), []byte(tag), []byte(value), implicit, implicit, style)) - e.emit() -} diff --git a/vendor/gopkg.in/yaml.v2/parserc.go b/vendor/gopkg.in/yaml.v2/parserc.go deleted file mode 100644 index 81d05dfe57..0000000000 --- a/vendor/gopkg.in/yaml.v2/parserc.go +++ /dev/null @@ -1,1095 +0,0 @@ -package yaml - -import ( - "bytes" -) - -// The parser implements the following grammar: -// -// stream ::= STREAM-START implicit_document? explicit_document* STREAM-END -// implicit_document ::= block_node DOCUMENT-END* -// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* -// block_node_or_indentless_sequence ::= -// ALIAS -// | properties (block_content | indentless_block_sequence)? -// | block_content -// | indentless_block_sequence -// block_node ::= ALIAS -// | properties block_content? -// | block_content -// flow_node ::= ALIAS -// | properties flow_content? -// | flow_content -// properties ::= TAG ANCHOR? | ANCHOR TAG? -// block_content ::= block_collection | flow_collection | SCALAR -// flow_content ::= flow_collection | SCALAR -// block_collection ::= block_sequence | block_mapping -// flow_collection ::= flow_sequence | flow_mapping -// block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END -// indentless_sequence ::= (BLOCK-ENTRY block_node?)+ -// block_mapping ::= BLOCK-MAPPING_START -// ((KEY block_node_or_indentless_sequence?)? -// (VALUE block_node_or_indentless_sequence?)?)* -// BLOCK-END -// flow_sequence ::= FLOW-SEQUENCE-START -// (flow_sequence_entry FLOW-ENTRY)* -// flow_sequence_entry? -// FLOW-SEQUENCE-END -// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? -// flow_mapping ::= FLOW-MAPPING-START -// (flow_mapping_entry FLOW-ENTRY)* -// flow_mapping_entry? -// FLOW-MAPPING-END -// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? - -// Peek the next token in the token queue. -func peek_token(parser *yaml_parser_t) *yaml_token_t { - if parser.token_available || yaml_parser_fetch_more_tokens(parser) { - return &parser.tokens[parser.tokens_head] - } - return nil -} - -// Remove the next token from the queue (must be called after peek_token). -func skip_token(parser *yaml_parser_t) { - parser.token_available = false - parser.tokens_parsed++ - parser.stream_end_produced = parser.tokens[parser.tokens_head].typ == yaml_STREAM_END_TOKEN - parser.tokens_head++ -} - -// Get the next event. -func yaml_parser_parse(parser *yaml_parser_t, event *yaml_event_t) bool { - // Erase the event object. - *event = yaml_event_t{} - - // No events after the end of the stream or error. - if parser.stream_end_produced || parser.error != yaml_NO_ERROR || parser.state == yaml_PARSE_END_STATE { - return true - } - - // Generate the next event. - return yaml_parser_state_machine(parser, event) -} - -// Set parser error. -func yaml_parser_set_parser_error(parser *yaml_parser_t, problem string, problem_mark yaml_mark_t) bool { - parser.error = yaml_PARSER_ERROR - parser.problem = problem - parser.problem_mark = problem_mark - return false -} - -func yaml_parser_set_parser_error_context(parser *yaml_parser_t, context string, context_mark yaml_mark_t, problem string, problem_mark yaml_mark_t) bool { - parser.error = yaml_PARSER_ERROR - parser.context = context - parser.context_mark = context_mark - parser.problem = problem - parser.problem_mark = problem_mark - return false -} - -// State dispatcher. -func yaml_parser_state_machine(parser *yaml_parser_t, event *yaml_event_t) bool { - //trace("yaml_parser_state_machine", "state:", parser.state.String()) - - switch parser.state { - case yaml_PARSE_STREAM_START_STATE: - return yaml_parser_parse_stream_start(parser, event) - - case yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE: - return yaml_parser_parse_document_start(parser, event, true) - - case yaml_PARSE_DOCUMENT_START_STATE: - return yaml_parser_parse_document_start(parser, event, false) - - case yaml_PARSE_DOCUMENT_CONTENT_STATE: - return yaml_parser_parse_document_content(parser, event) - - case yaml_PARSE_DOCUMENT_END_STATE: - return yaml_parser_parse_document_end(parser, event) - - case yaml_PARSE_BLOCK_NODE_STATE: - return yaml_parser_parse_node(parser, event, true, false) - - case yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE: - return yaml_parser_parse_node(parser, event, true, true) - - case yaml_PARSE_FLOW_NODE_STATE: - return yaml_parser_parse_node(parser, event, false, false) - - case yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE: - return yaml_parser_parse_block_sequence_entry(parser, event, true) - - case yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE: - return yaml_parser_parse_block_sequence_entry(parser, event, false) - - case yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE: - return yaml_parser_parse_indentless_sequence_entry(parser, event) - - case yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE: - return yaml_parser_parse_block_mapping_key(parser, event, true) - - case yaml_PARSE_BLOCK_MAPPING_KEY_STATE: - return yaml_parser_parse_block_mapping_key(parser, event, false) - - case yaml_PARSE_BLOCK_MAPPING_VALUE_STATE: - return yaml_parser_parse_block_mapping_value(parser, event) - - case yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE: - return yaml_parser_parse_flow_sequence_entry(parser, event, true) - - case yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE: - return yaml_parser_parse_flow_sequence_entry(parser, event, false) - - case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE: - return yaml_parser_parse_flow_sequence_entry_mapping_key(parser, event) - - case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE: - return yaml_parser_parse_flow_sequence_entry_mapping_value(parser, event) - - case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE: - return yaml_parser_parse_flow_sequence_entry_mapping_end(parser, event) - - case yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE: - return yaml_parser_parse_flow_mapping_key(parser, event, true) - - case yaml_PARSE_FLOW_MAPPING_KEY_STATE: - return yaml_parser_parse_flow_mapping_key(parser, event, false) - - case yaml_PARSE_FLOW_MAPPING_VALUE_STATE: - return yaml_parser_parse_flow_mapping_value(parser, event, false) - - case yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE: - return yaml_parser_parse_flow_mapping_value(parser, event, true) - - default: - panic("invalid parser state") - } -} - -// Parse the production: -// stream ::= STREAM-START implicit_document? explicit_document* STREAM-END -// ************ -func yaml_parser_parse_stream_start(parser *yaml_parser_t, event *yaml_event_t) bool { - token := peek_token(parser) - if token == nil { - return false - } - if token.typ != yaml_STREAM_START_TOKEN { - return yaml_parser_set_parser_error(parser, "did not find expected ", token.start_mark) - } - parser.state = yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE - *event = yaml_event_t{ - typ: yaml_STREAM_START_EVENT, - start_mark: token.start_mark, - end_mark: token.end_mark, - encoding: token.encoding, - } - skip_token(parser) - return true -} - -// Parse the productions: -// implicit_document ::= block_node DOCUMENT-END* -// * -// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* -// ************************* -func yaml_parser_parse_document_start(parser *yaml_parser_t, event *yaml_event_t, implicit bool) bool { - - token := peek_token(parser) - if token == nil { - return false - } - - // Parse extra document end indicators. - if !implicit { - for token.typ == yaml_DOCUMENT_END_TOKEN { - skip_token(parser) - token = peek_token(parser) - if token == nil { - return false - } - } - } - - if implicit && token.typ != yaml_VERSION_DIRECTIVE_TOKEN && - token.typ != yaml_TAG_DIRECTIVE_TOKEN && - token.typ != yaml_DOCUMENT_START_TOKEN && - token.typ != yaml_STREAM_END_TOKEN { - // Parse an implicit document. - if !yaml_parser_process_directives(parser, nil, nil) { - return false - } - parser.states = append(parser.states, yaml_PARSE_DOCUMENT_END_STATE) - parser.state = yaml_PARSE_BLOCK_NODE_STATE - - *event = yaml_event_t{ - typ: yaml_DOCUMENT_START_EVENT, - start_mark: token.start_mark, - end_mark: token.end_mark, - } - - } else if token.typ != yaml_STREAM_END_TOKEN { - // Parse an explicit document. - var version_directive *yaml_version_directive_t - var tag_directives []yaml_tag_directive_t - start_mark := token.start_mark - if !yaml_parser_process_directives(parser, &version_directive, &tag_directives) { - return false - } - token = peek_token(parser) - if token == nil { - return false - } - if token.typ != yaml_DOCUMENT_START_TOKEN { - yaml_parser_set_parser_error(parser, - "did not find expected ", token.start_mark) - return false - } - parser.states = append(parser.states, yaml_PARSE_DOCUMENT_END_STATE) - parser.state = yaml_PARSE_DOCUMENT_CONTENT_STATE - end_mark := token.end_mark - - *event = yaml_event_t{ - typ: yaml_DOCUMENT_START_EVENT, - start_mark: start_mark, - end_mark: end_mark, - version_directive: version_directive, - tag_directives: tag_directives, - implicit: false, - } - skip_token(parser) - - } else { - // Parse the stream end. - parser.state = yaml_PARSE_END_STATE - *event = yaml_event_t{ - typ: yaml_STREAM_END_EVENT, - start_mark: token.start_mark, - end_mark: token.end_mark, - } - skip_token(parser) - } - - return true -} - -// Parse the productions: -// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* -// *********** -// -func yaml_parser_parse_document_content(parser *yaml_parser_t, event *yaml_event_t) bool { - token := peek_token(parser) - if token == nil { - return false - } - if token.typ == yaml_VERSION_DIRECTIVE_TOKEN || - token.typ == yaml_TAG_DIRECTIVE_TOKEN || - token.typ == yaml_DOCUMENT_START_TOKEN || - token.typ == yaml_DOCUMENT_END_TOKEN || - token.typ == yaml_STREAM_END_TOKEN { - parser.state = parser.states[len(parser.states)-1] - parser.states = parser.states[:len(parser.states)-1] - return yaml_parser_process_empty_scalar(parser, event, - token.start_mark) - } - return yaml_parser_parse_node(parser, event, true, false) -} - -// Parse the productions: -// implicit_document ::= block_node DOCUMENT-END* -// ************* -// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* -// -func yaml_parser_parse_document_end(parser *yaml_parser_t, event *yaml_event_t) bool { - token := peek_token(parser) - if token == nil { - return false - } - - start_mark := token.start_mark - end_mark := token.start_mark - - implicit := true - if token.typ == yaml_DOCUMENT_END_TOKEN { - end_mark = token.end_mark - skip_token(parser) - implicit = false - } - - parser.tag_directives = parser.tag_directives[:0] - - parser.state = yaml_PARSE_DOCUMENT_START_STATE - *event = yaml_event_t{ - typ: yaml_DOCUMENT_END_EVENT, - start_mark: start_mark, - end_mark: end_mark, - implicit: implicit, - } - return true -} - -// Parse the productions: -// block_node_or_indentless_sequence ::= -// ALIAS -// ***** -// | properties (block_content | indentless_block_sequence)? -// ********** * -// | block_content | indentless_block_sequence -// * -// block_node ::= ALIAS -// ***** -// | properties block_content? -// ********** * -// | block_content -// * -// flow_node ::= ALIAS -// ***** -// | properties flow_content? -// ********** * -// | flow_content -// * -// properties ::= TAG ANCHOR? | ANCHOR TAG? -// ************************* -// block_content ::= block_collection | flow_collection | SCALAR -// ****** -// flow_content ::= flow_collection | SCALAR -// ****** -func yaml_parser_parse_node(parser *yaml_parser_t, event *yaml_event_t, block, indentless_sequence bool) bool { - //defer trace("yaml_parser_parse_node", "block:", block, "indentless_sequence:", indentless_sequence)() - - token := peek_token(parser) - if token == nil { - return false - } - - if token.typ == yaml_ALIAS_TOKEN { - parser.state = parser.states[len(parser.states)-1] - parser.states = parser.states[:len(parser.states)-1] - *event = yaml_event_t{ - typ: yaml_ALIAS_EVENT, - start_mark: token.start_mark, - end_mark: token.end_mark, - anchor: token.value, - } - skip_token(parser) - return true - } - - start_mark := token.start_mark - end_mark := token.start_mark - - var tag_token bool - var tag_handle, tag_suffix, anchor []byte - var tag_mark yaml_mark_t - if token.typ == yaml_ANCHOR_TOKEN { - anchor = token.value - start_mark = token.start_mark - end_mark = token.end_mark - skip_token(parser) - token = peek_token(parser) - if token == nil { - return false - } - if token.typ == yaml_TAG_TOKEN { - tag_token = true - tag_handle = token.value - tag_suffix = token.suffix - tag_mark = token.start_mark - end_mark = token.end_mark - skip_token(parser) - token = peek_token(parser) - if token == nil { - return false - } - } - } else if token.typ == yaml_TAG_TOKEN { - tag_token = true - tag_handle = token.value - tag_suffix = token.suffix - start_mark = token.start_mark - tag_mark = token.start_mark - end_mark = token.end_mark - skip_token(parser) - token = peek_token(parser) - if token == nil { - return false - } - if token.typ == yaml_ANCHOR_TOKEN { - anchor = token.value - end_mark = token.end_mark - skip_token(parser) - token = peek_token(parser) - if token == nil { - return false - } - } - } - - var tag []byte - if tag_token { - if len(tag_handle) == 0 { - tag = tag_suffix - tag_suffix = nil - } else { - for i := range parser.tag_directives { - if bytes.Equal(parser.tag_directives[i].handle, tag_handle) { - tag = append([]byte(nil), parser.tag_directives[i].prefix...) - tag = append(tag, tag_suffix...) - break - } - } - if len(tag) == 0 { - yaml_parser_set_parser_error_context(parser, - "while parsing a node", start_mark, - "found undefined tag handle", tag_mark) - return false - } - } - } - - implicit := len(tag) == 0 - if indentless_sequence && token.typ == yaml_BLOCK_ENTRY_TOKEN { - end_mark = token.end_mark - parser.state = yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE - *event = yaml_event_t{ - typ: yaml_SEQUENCE_START_EVENT, - start_mark: start_mark, - end_mark: end_mark, - anchor: anchor, - tag: tag, - implicit: implicit, - style: yaml_style_t(yaml_BLOCK_SEQUENCE_STYLE), - } - return true - } - if token.typ == yaml_SCALAR_TOKEN { - var plain_implicit, quoted_implicit bool - end_mark = token.end_mark - if (len(tag) == 0 && token.style == yaml_PLAIN_SCALAR_STYLE) || (len(tag) == 1 && tag[0] == '!') { - plain_implicit = true - } else if len(tag) == 0 { - quoted_implicit = true - } - parser.state = parser.states[len(parser.states)-1] - parser.states = parser.states[:len(parser.states)-1] - - *event = yaml_event_t{ - typ: yaml_SCALAR_EVENT, - start_mark: start_mark, - end_mark: end_mark, - anchor: anchor, - tag: tag, - value: token.value, - implicit: plain_implicit, - quoted_implicit: quoted_implicit, - style: yaml_style_t(token.style), - } - skip_token(parser) - return true - } - if token.typ == yaml_FLOW_SEQUENCE_START_TOKEN { - // [Go] Some of the events below can be merged as they differ only on style. - end_mark = token.end_mark - parser.state = yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE - *event = yaml_event_t{ - typ: yaml_SEQUENCE_START_EVENT, - start_mark: start_mark, - end_mark: end_mark, - anchor: anchor, - tag: tag, - implicit: implicit, - style: yaml_style_t(yaml_FLOW_SEQUENCE_STYLE), - } - return true - } - if token.typ == yaml_FLOW_MAPPING_START_TOKEN { - end_mark = token.end_mark - parser.state = yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE - *event = yaml_event_t{ - typ: yaml_MAPPING_START_EVENT, - start_mark: start_mark, - end_mark: end_mark, - anchor: anchor, - tag: tag, - implicit: implicit, - style: yaml_style_t(yaml_FLOW_MAPPING_STYLE), - } - return true - } - if block && token.typ == yaml_BLOCK_SEQUENCE_START_TOKEN { - end_mark = token.end_mark - parser.state = yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE - *event = yaml_event_t{ - typ: yaml_SEQUENCE_START_EVENT, - start_mark: start_mark, - end_mark: end_mark, - anchor: anchor, - tag: tag, - implicit: implicit, - style: yaml_style_t(yaml_BLOCK_SEQUENCE_STYLE), - } - return true - } - if block && token.typ == yaml_BLOCK_MAPPING_START_TOKEN { - end_mark = token.end_mark - parser.state = yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE - *event = yaml_event_t{ - typ: yaml_MAPPING_START_EVENT, - start_mark: start_mark, - end_mark: end_mark, - anchor: anchor, - tag: tag, - implicit: implicit, - style: yaml_style_t(yaml_BLOCK_MAPPING_STYLE), - } - return true - } - if len(anchor) > 0 || len(tag) > 0 { - parser.state = parser.states[len(parser.states)-1] - parser.states = parser.states[:len(parser.states)-1] - - *event = yaml_event_t{ - typ: yaml_SCALAR_EVENT, - start_mark: start_mark, - end_mark: end_mark, - anchor: anchor, - tag: tag, - implicit: implicit, - quoted_implicit: false, - style: yaml_style_t(yaml_PLAIN_SCALAR_STYLE), - } - return true - } - - context := "while parsing a flow node" - if block { - context = "while parsing a block node" - } - yaml_parser_set_parser_error_context(parser, context, start_mark, - "did not find expected node content", token.start_mark) - return false -} - -// Parse the productions: -// block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END -// ******************** *********** * ********* -// -func yaml_parser_parse_block_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { - if first { - token := peek_token(parser) - parser.marks = append(parser.marks, token.start_mark) - skip_token(parser) - } - - token := peek_token(parser) - if token == nil { - return false - } - - if token.typ == yaml_BLOCK_ENTRY_TOKEN { - mark := token.end_mark - skip_token(parser) - token = peek_token(parser) - if token == nil { - return false - } - if token.typ != yaml_BLOCK_ENTRY_TOKEN && token.typ != yaml_BLOCK_END_TOKEN { - parser.states = append(parser.states, yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE) - return yaml_parser_parse_node(parser, event, true, false) - } else { - parser.state = yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE - return yaml_parser_process_empty_scalar(parser, event, mark) - } - } - if token.typ == yaml_BLOCK_END_TOKEN { - parser.state = parser.states[len(parser.states)-1] - parser.states = parser.states[:len(parser.states)-1] - parser.marks = parser.marks[:len(parser.marks)-1] - - *event = yaml_event_t{ - typ: yaml_SEQUENCE_END_EVENT, - start_mark: token.start_mark, - end_mark: token.end_mark, - } - - skip_token(parser) - return true - } - - context_mark := parser.marks[len(parser.marks)-1] - parser.marks = parser.marks[:len(parser.marks)-1] - return yaml_parser_set_parser_error_context(parser, - "while parsing a block collection", context_mark, - "did not find expected '-' indicator", token.start_mark) -} - -// Parse the productions: -// indentless_sequence ::= (BLOCK-ENTRY block_node?)+ -// *********** * -func yaml_parser_parse_indentless_sequence_entry(parser *yaml_parser_t, event *yaml_event_t) bool { - token := peek_token(parser) - if token == nil { - return false - } - - if token.typ == yaml_BLOCK_ENTRY_TOKEN { - mark := token.end_mark - skip_token(parser) - token = peek_token(parser) - if token == nil { - return false - } - if token.typ != yaml_BLOCK_ENTRY_TOKEN && - token.typ != yaml_KEY_TOKEN && - token.typ != yaml_VALUE_TOKEN && - token.typ != yaml_BLOCK_END_TOKEN { - parser.states = append(parser.states, yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE) - return yaml_parser_parse_node(parser, event, true, false) - } - parser.state = yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE - return yaml_parser_process_empty_scalar(parser, event, mark) - } - parser.state = parser.states[len(parser.states)-1] - parser.states = parser.states[:len(parser.states)-1] - - *event = yaml_event_t{ - typ: yaml_SEQUENCE_END_EVENT, - start_mark: token.start_mark, - end_mark: token.start_mark, // [Go] Shouldn't this be token.end_mark? - } - return true -} - -// Parse the productions: -// block_mapping ::= BLOCK-MAPPING_START -// ******************* -// ((KEY block_node_or_indentless_sequence?)? -// *** * -// (VALUE block_node_or_indentless_sequence?)?)* -// -// BLOCK-END -// ********* -// -func yaml_parser_parse_block_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { - if first { - token := peek_token(parser) - parser.marks = append(parser.marks, token.start_mark) - skip_token(parser) - } - - token := peek_token(parser) - if token == nil { - return false - } - - if token.typ == yaml_KEY_TOKEN { - mark := token.end_mark - skip_token(parser) - token = peek_token(parser) - if token == nil { - return false - } - if token.typ != yaml_KEY_TOKEN && - token.typ != yaml_VALUE_TOKEN && - token.typ != yaml_BLOCK_END_TOKEN { - parser.states = append(parser.states, yaml_PARSE_BLOCK_MAPPING_VALUE_STATE) - return yaml_parser_parse_node(parser, event, true, true) - } else { - parser.state = yaml_PARSE_BLOCK_MAPPING_VALUE_STATE - return yaml_parser_process_empty_scalar(parser, event, mark) - } - } else if token.typ == yaml_BLOCK_END_TOKEN { - parser.state = parser.states[len(parser.states)-1] - parser.states = parser.states[:len(parser.states)-1] - parser.marks = parser.marks[:len(parser.marks)-1] - *event = yaml_event_t{ - typ: yaml_MAPPING_END_EVENT, - start_mark: token.start_mark, - end_mark: token.end_mark, - } - skip_token(parser) - return true - } - - context_mark := parser.marks[len(parser.marks)-1] - parser.marks = parser.marks[:len(parser.marks)-1] - return yaml_parser_set_parser_error_context(parser, - "while parsing a block mapping", context_mark, - "did not find expected key", token.start_mark) -} - -// Parse the productions: -// block_mapping ::= BLOCK-MAPPING_START -// -// ((KEY block_node_or_indentless_sequence?)? -// -// (VALUE block_node_or_indentless_sequence?)?)* -// ***** * -// BLOCK-END -// -// -func yaml_parser_parse_block_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool { - token := peek_token(parser) - if token == nil { - return false - } - if token.typ == yaml_VALUE_TOKEN { - mark := token.end_mark - skip_token(parser) - token = peek_token(parser) - if token == nil { - return false - } - if token.typ != yaml_KEY_TOKEN && - token.typ != yaml_VALUE_TOKEN && - token.typ != yaml_BLOCK_END_TOKEN { - parser.states = append(parser.states, yaml_PARSE_BLOCK_MAPPING_KEY_STATE) - return yaml_parser_parse_node(parser, event, true, true) - } - parser.state = yaml_PARSE_BLOCK_MAPPING_KEY_STATE - return yaml_parser_process_empty_scalar(parser, event, mark) - } - parser.state = yaml_PARSE_BLOCK_MAPPING_KEY_STATE - return yaml_parser_process_empty_scalar(parser, event, token.start_mark) -} - -// Parse the productions: -// flow_sequence ::= FLOW-SEQUENCE-START -// ******************* -// (flow_sequence_entry FLOW-ENTRY)* -// * ********** -// flow_sequence_entry? -// * -// FLOW-SEQUENCE-END -// ***************** -// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? -// * -// -func yaml_parser_parse_flow_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { - if first { - token := peek_token(parser) - parser.marks = append(parser.marks, token.start_mark) - skip_token(parser) - } - token := peek_token(parser) - if token == nil { - return false - } - if token.typ != yaml_FLOW_SEQUENCE_END_TOKEN { - if !first { - if token.typ == yaml_FLOW_ENTRY_TOKEN { - skip_token(parser) - token = peek_token(parser) - if token == nil { - return false - } - } else { - context_mark := parser.marks[len(parser.marks)-1] - parser.marks = parser.marks[:len(parser.marks)-1] - return yaml_parser_set_parser_error_context(parser, - "while parsing a flow sequence", context_mark, - "did not find expected ',' or ']'", token.start_mark) - } - } - - if token.typ == yaml_KEY_TOKEN { - parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE - *event = yaml_event_t{ - typ: yaml_MAPPING_START_EVENT, - start_mark: token.start_mark, - end_mark: token.end_mark, - implicit: true, - style: yaml_style_t(yaml_FLOW_MAPPING_STYLE), - } - skip_token(parser) - return true - } else if token.typ != yaml_FLOW_SEQUENCE_END_TOKEN { - parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE) - return yaml_parser_parse_node(parser, event, false, false) - } - } - - parser.state = parser.states[len(parser.states)-1] - parser.states = parser.states[:len(parser.states)-1] - parser.marks = parser.marks[:len(parser.marks)-1] - - *event = yaml_event_t{ - typ: yaml_SEQUENCE_END_EVENT, - start_mark: token.start_mark, - end_mark: token.end_mark, - } - - skip_token(parser) - return true -} - -// -// Parse the productions: -// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? -// *** * -// -func yaml_parser_parse_flow_sequence_entry_mapping_key(parser *yaml_parser_t, event *yaml_event_t) bool { - token := peek_token(parser) - if token == nil { - return false - } - if token.typ != yaml_VALUE_TOKEN && - token.typ != yaml_FLOW_ENTRY_TOKEN && - token.typ != yaml_FLOW_SEQUENCE_END_TOKEN { - parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE) - return yaml_parser_parse_node(parser, event, false, false) - } - mark := token.end_mark - skip_token(parser) - parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE - return yaml_parser_process_empty_scalar(parser, event, mark) -} - -// Parse the productions: -// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? -// ***** * -// -func yaml_parser_parse_flow_sequence_entry_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool { - token := peek_token(parser) - if token == nil { - return false - } - if token.typ == yaml_VALUE_TOKEN { - skip_token(parser) - token := peek_token(parser) - if token == nil { - return false - } - if token.typ != yaml_FLOW_ENTRY_TOKEN && token.typ != yaml_FLOW_SEQUENCE_END_TOKEN { - parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE) - return yaml_parser_parse_node(parser, event, false, false) - } - } - parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE - return yaml_parser_process_empty_scalar(parser, event, token.start_mark) -} - -// Parse the productions: -// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? -// * -// -func yaml_parser_parse_flow_sequence_entry_mapping_end(parser *yaml_parser_t, event *yaml_event_t) bool { - token := peek_token(parser) - if token == nil { - return false - } - parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE - *event = yaml_event_t{ - typ: yaml_MAPPING_END_EVENT, - start_mark: token.start_mark, - end_mark: token.start_mark, // [Go] Shouldn't this be end_mark? - } - return true -} - -// Parse the productions: -// flow_mapping ::= FLOW-MAPPING-START -// ****************** -// (flow_mapping_entry FLOW-ENTRY)* -// * ********** -// flow_mapping_entry? -// ****************** -// FLOW-MAPPING-END -// **************** -// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? -// * *** * -// -func yaml_parser_parse_flow_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { - if first { - token := peek_token(parser) - parser.marks = append(parser.marks, token.start_mark) - skip_token(parser) - } - - token := peek_token(parser) - if token == nil { - return false - } - - if token.typ != yaml_FLOW_MAPPING_END_TOKEN { - if !first { - if token.typ == yaml_FLOW_ENTRY_TOKEN { - skip_token(parser) - token = peek_token(parser) - if token == nil { - return false - } - } else { - context_mark := parser.marks[len(parser.marks)-1] - parser.marks = parser.marks[:len(parser.marks)-1] - return yaml_parser_set_parser_error_context(parser, - "while parsing a flow mapping", context_mark, - "did not find expected ',' or '}'", token.start_mark) - } - } - - if token.typ == yaml_KEY_TOKEN { - skip_token(parser) - token = peek_token(parser) - if token == nil { - return false - } - if token.typ != yaml_VALUE_TOKEN && - token.typ != yaml_FLOW_ENTRY_TOKEN && - token.typ != yaml_FLOW_MAPPING_END_TOKEN { - parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_VALUE_STATE) - return yaml_parser_parse_node(parser, event, false, false) - } else { - parser.state = yaml_PARSE_FLOW_MAPPING_VALUE_STATE - return yaml_parser_process_empty_scalar(parser, event, token.start_mark) - } - } else if token.typ != yaml_FLOW_MAPPING_END_TOKEN { - parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE) - return yaml_parser_parse_node(parser, event, false, false) - } - } - - parser.state = parser.states[len(parser.states)-1] - parser.states = parser.states[:len(parser.states)-1] - parser.marks = parser.marks[:len(parser.marks)-1] - *event = yaml_event_t{ - typ: yaml_MAPPING_END_EVENT, - start_mark: token.start_mark, - end_mark: token.end_mark, - } - skip_token(parser) - return true -} - -// Parse the productions: -// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? -// * ***** * -// -func yaml_parser_parse_flow_mapping_value(parser *yaml_parser_t, event *yaml_event_t, empty bool) bool { - token := peek_token(parser) - if token == nil { - return false - } - if empty { - parser.state = yaml_PARSE_FLOW_MAPPING_KEY_STATE - return yaml_parser_process_empty_scalar(parser, event, token.start_mark) - } - if token.typ == yaml_VALUE_TOKEN { - skip_token(parser) - token = peek_token(parser) - if token == nil { - return false - } - if token.typ != yaml_FLOW_ENTRY_TOKEN && token.typ != yaml_FLOW_MAPPING_END_TOKEN { - parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_KEY_STATE) - return yaml_parser_parse_node(parser, event, false, false) - } - } - parser.state = yaml_PARSE_FLOW_MAPPING_KEY_STATE - return yaml_parser_process_empty_scalar(parser, event, token.start_mark) -} - -// Generate an empty scalar event. -func yaml_parser_process_empty_scalar(parser *yaml_parser_t, event *yaml_event_t, mark yaml_mark_t) bool { - *event = yaml_event_t{ - typ: yaml_SCALAR_EVENT, - start_mark: mark, - end_mark: mark, - value: nil, // Empty - implicit: true, - style: yaml_style_t(yaml_PLAIN_SCALAR_STYLE), - } - return true -} - -var default_tag_directives = []yaml_tag_directive_t{ - {[]byte("!"), []byte("!")}, - {[]byte("!!"), []byte("tag:yaml.org,2002:")}, -} - -// Parse directives. -func yaml_parser_process_directives(parser *yaml_parser_t, - version_directive_ref **yaml_version_directive_t, - tag_directives_ref *[]yaml_tag_directive_t) bool { - - var version_directive *yaml_version_directive_t - var tag_directives []yaml_tag_directive_t - - token := peek_token(parser) - if token == nil { - return false - } - - for token.typ == yaml_VERSION_DIRECTIVE_TOKEN || token.typ == yaml_TAG_DIRECTIVE_TOKEN { - if token.typ == yaml_VERSION_DIRECTIVE_TOKEN { - if version_directive != nil { - yaml_parser_set_parser_error(parser, - "found duplicate %YAML directive", token.start_mark) - return false - } - if token.major != 1 || token.minor != 1 { - yaml_parser_set_parser_error(parser, - "found incompatible YAML document", token.start_mark) - return false - } - version_directive = &yaml_version_directive_t{ - major: token.major, - minor: token.minor, - } - } else if token.typ == yaml_TAG_DIRECTIVE_TOKEN { - value := yaml_tag_directive_t{ - handle: token.value, - prefix: token.prefix, - } - if !yaml_parser_append_tag_directive(parser, value, false, token.start_mark) { - return false - } - tag_directives = append(tag_directives, value) - } - - skip_token(parser) - token = peek_token(parser) - if token == nil { - return false - } - } - - for i := range default_tag_directives { - if !yaml_parser_append_tag_directive(parser, default_tag_directives[i], true, token.start_mark) { - return false - } - } - - if version_directive_ref != nil { - *version_directive_ref = version_directive - } - if tag_directives_ref != nil { - *tag_directives_ref = tag_directives - } - return true -} - -// Append a tag directive to the directives stack. -func yaml_parser_append_tag_directive(parser *yaml_parser_t, value yaml_tag_directive_t, allow_duplicates bool, mark yaml_mark_t) bool { - for i := range parser.tag_directives { - if bytes.Equal(value.handle, parser.tag_directives[i].handle) { - if allow_duplicates { - return true - } - return yaml_parser_set_parser_error(parser, "found duplicate %TAG directive", mark) - } - } - - // [Go] I suspect the copy is unnecessary. This was likely done - // because there was no way to track ownership of the data. - value_copy := yaml_tag_directive_t{ - handle: make([]byte, len(value.handle)), - prefix: make([]byte, len(value.prefix)), - } - copy(value_copy.handle, value.handle) - copy(value_copy.prefix, value.prefix) - parser.tag_directives = append(parser.tag_directives, value_copy) - return true -} diff --git a/vendor/gopkg.in/yaml.v2/readerc.go b/vendor/gopkg.in/yaml.v2/readerc.go deleted file mode 100644 index 7c1f5fac3d..0000000000 --- a/vendor/gopkg.in/yaml.v2/readerc.go +++ /dev/null @@ -1,412 +0,0 @@ -package yaml - -import ( - "io" -) - -// Set the reader error and return 0. -func yaml_parser_set_reader_error(parser *yaml_parser_t, problem string, offset int, value int) bool { - parser.error = yaml_READER_ERROR - parser.problem = problem - parser.problem_offset = offset - parser.problem_value = value - return false -} - -// Byte order marks. -const ( - bom_UTF8 = "\xef\xbb\xbf" - bom_UTF16LE = "\xff\xfe" - bom_UTF16BE = "\xfe\xff" -) - -// Determine the input stream encoding by checking the BOM symbol. If no BOM is -// found, the UTF-8 encoding is assumed. Return 1 on success, 0 on failure. -func yaml_parser_determine_encoding(parser *yaml_parser_t) bool { - // Ensure that we had enough bytes in the raw buffer. - for !parser.eof && len(parser.raw_buffer)-parser.raw_buffer_pos < 3 { - if !yaml_parser_update_raw_buffer(parser) { - return false - } - } - - // Determine the encoding. - buf := parser.raw_buffer - pos := parser.raw_buffer_pos - avail := len(buf) - pos - if avail >= 2 && buf[pos] == bom_UTF16LE[0] && buf[pos+1] == bom_UTF16LE[1] { - parser.encoding = yaml_UTF16LE_ENCODING - parser.raw_buffer_pos += 2 - parser.offset += 2 - } else if avail >= 2 && buf[pos] == bom_UTF16BE[0] && buf[pos+1] == bom_UTF16BE[1] { - parser.encoding = yaml_UTF16BE_ENCODING - parser.raw_buffer_pos += 2 - parser.offset += 2 - } else if avail >= 3 && buf[pos] == bom_UTF8[0] && buf[pos+1] == bom_UTF8[1] && buf[pos+2] == bom_UTF8[2] { - parser.encoding = yaml_UTF8_ENCODING - parser.raw_buffer_pos += 3 - parser.offset += 3 - } else { - parser.encoding = yaml_UTF8_ENCODING - } - return true -} - -// Update the raw buffer. -func yaml_parser_update_raw_buffer(parser *yaml_parser_t) bool { - size_read := 0 - - // Return if the raw buffer is full. - if parser.raw_buffer_pos == 0 && len(parser.raw_buffer) == cap(parser.raw_buffer) { - return true - } - - // Return on EOF. - if parser.eof { - return true - } - - // Move the remaining bytes in the raw buffer to the beginning. - if parser.raw_buffer_pos > 0 && parser.raw_buffer_pos < len(parser.raw_buffer) { - copy(parser.raw_buffer, parser.raw_buffer[parser.raw_buffer_pos:]) - } - parser.raw_buffer = parser.raw_buffer[:len(parser.raw_buffer)-parser.raw_buffer_pos] - parser.raw_buffer_pos = 0 - - // Call the read handler to fill the buffer. - size_read, err := parser.read_handler(parser, parser.raw_buffer[len(parser.raw_buffer):cap(parser.raw_buffer)]) - parser.raw_buffer = parser.raw_buffer[:len(parser.raw_buffer)+size_read] - if err == io.EOF { - parser.eof = true - } else if err != nil { - return yaml_parser_set_reader_error(parser, "input error: "+err.Error(), parser.offset, -1) - } - return true -} - -// Ensure that the buffer contains at least `length` characters. -// Return true on success, false on failure. -// -// The length is supposed to be significantly less that the buffer size. -func yaml_parser_update_buffer(parser *yaml_parser_t, length int) bool { - if parser.read_handler == nil { - panic("read handler must be set") - } - - // [Go] This function was changed to guarantee the requested length size at EOF. - // The fact we need to do this is pretty awful, but the description above implies - // for that to be the case, and there are tests - - // If the EOF flag is set and the raw buffer is empty, do nothing. - if parser.eof && parser.raw_buffer_pos == len(parser.raw_buffer) { - // [Go] ACTUALLY! Read the documentation of this function above. - // This is just broken. To return true, we need to have the - // given length in the buffer. Not doing that means every single - // check that calls this function to make sure the buffer has a - // given length is Go) panicking; or C) accessing invalid memory. - //return true - } - - // Return if the buffer contains enough characters. - if parser.unread >= length { - return true - } - - // Determine the input encoding if it is not known yet. - if parser.encoding == yaml_ANY_ENCODING { - if !yaml_parser_determine_encoding(parser) { - return false - } - } - - // Move the unread characters to the beginning of the buffer. - buffer_len := len(parser.buffer) - if parser.buffer_pos > 0 && parser.buffer_pos < buffer_len { - copy(parser.buffer, parser.buffer[parser.buffer_pos:]) - buffer_len -= parser.buffer_pos - parser.buffer_pos = 0 - } else if parser.buffer_pos == buffer_len { - buffer_len = 0 - parser.buffer_pos = 0 - } - - // Open the whole buffer for writing, and cut it before returning. - parser.buffer = parser.buffer[:cap(parser.buffer)] - - // Fill the buffer until it has enough characters. - first := true - for parser.unread < length { - - // Fill the raw buffer if necessary. - if !first || parser.raw_buffer_pos == len(parser.raw_buffer) { - if !yaml_parser_update_raw_buffer(parser) { - parser.buffer = parser.buffer[:buffer_len] - return false - } - } - first = false - - // Decode the raw buffer. - inner: - for parser.raw_buffer_pos != len(parser.raw_buffer) { - var value rune - var width int - - raw_unread := len(parser.raw_buffer) - parser.raw_buffer_pos - - // Decode the next character. - switch parser.encoding { - case yaml_UTF8_ENCODING: - // Decode a UTF-8 character. Check RFC 3629 - // (http://www.ietf.org/rfc/rfc3629.txt) for more details. - // - // The following table (taken from the RFC) is used for - // decoding. - // - // Char. number range | UTF-8 octet sequence - // (hexadecimal) | (binary) - // --------------------+------------------------------------ - // 0000 0000-0000 007F | 0xxxxxxx - // 0000 0080-0000 07FF | 110xxxxx 10xxxxxx - // 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx - // 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx - // - // Additionally, the characters in the range 0xD800-0xDFFF - // are prohibited as they are reserved for use with UTF-16 - // surrogate pairs. - - // Determine the length of the UTF-8 sequence. - octet := parser.raw_buffer[parser.raw_buffer_pos] - switch { - case octet&0x80 == 0x00: - width = 1 - case octet&0xE0 == 0xC0: - width = 2 - case octet&0xF0 == 0xE0: - width = 3 - case octet&0xF8 == 0xF0: - width = 4 - default: - // The leading octet is invalid. - return yaml_parser_set_reader_error(parser, - "invalid leading UTF-8 octet", - parser.offset, int(octet)) - } - - // Check if the raw buffer contains an incomplete character. - if width > raw_unread { - if parser.eof { - return yaml_parser_set_reader_error(parser, - "incomplete UTF-8 octet sequence", - parser.offset, -1) - } - break inner - } - - // Decode the leading octet. - switch { - case octet&0x80 == 0x00: - value = rune(octet & 0x7F) - case octet&0xE0 == 0xC0: - value = rune(octet & 0x1F) - case octet&0xF0 == 0xE0: - value = rune(octet & 0x0F) - case octet&0xF8 == 0xF0: - value = rune(octet & 0x07) - default: - value = 0 - } - - // Check and decode the trailing octets. - for k := 1; k < width; k++ { - octet = parser.raw_buffer[parser.raw_buffer_pos+k] - - // Check if the octet is valid. - if (octet & 0xC0) != 0x80 { - return yaml_parser_set_reader_error(parser, - "invalid trailing UTF-8 octet", - parser.offset+k, int(octet)) - } - - // Decode the octet. - value = (value << 6) + rune(octet&0x3F) - } - - // Check the length of the sequence against the value. - switch { - case width == 1: - case width == 2 && value >= 0x80: - case width == 3 && value >= 0x800: - case width == 4 && value >= 0x10000: - default: - return yaml_parser_set_reader_error(parser, - "invalid length of a UTF-8 sequence", - parser.offset, -1) - } - - // Check the range of the value. - if value >= 0xD800 && value <= 0xDFFF || value > 0x10FFFF { - return yaml_parser_set_reader_error(parser, - "invalid Unicode character", - parser.offset, int(value)) - } - - case yaml_UTF16LE_ENCODING, yaml_UTF16BE_ENCODING: - var low, high int - if parser.encoding == yaml_UTF16LE_ENCODING { - low, high = 0, 1 - } else { - low, high = 1, 0 - } - - // The UTF-16 encoding is not as simple as one might - // naively think. Check RFC 2781 - // (http://www.ietf.org/rfc/rfc2781.txt). - // - // Normally, two subsequent bytes describe a Unicode - // character. However a special technique (called a - // surrogate pair) is used for specifying character - // values larger than 0xFFFF. - // - // A surrogate pair consists of two pseudo-characters: - // high surrogate area (0xD800-0xDBFF) - // low surrogate area (0xDC00-0xDFFF) - // - // The following formulas are used for decoding - // and encoding characters using surrogate pairs: - // - // U = U' + 0x10000 (0x01 00 00 <= U <= 0x10 FF FF) - // U' = yyyyyyyyyyxxxxxxxxxx (0 <= U' <= 0x0F FF FF) - // W1 = 110110yyyyyyyyyy - // W2 = 110111xxxxxxxxxx - // - // where U is the character value, W1 is the high surrogate - // area, W2 is the low surrogate area. - - // Check for incomplete UTF-16 character. - if raw_unread < 2 { - if parser.eof { - return yaml_parser_set_reader_error(parser, - "incomplete UTF-16 character", - parser.offset, -1) - } - break inner - } - - // Get the character. - value = rune(parser.raw_buffer[parser.raw_buffer_pos+low]) + - (rune(parser.raw_buffer[parser.raw_buffer_pos+high]) << 8) - - // Check for unexpected low surrogate area. - if value&0xFC00 == 0xDC00 { - return yaml_parser_set_reader_error(parser, - "unexpected low surrogate area", - parser.offset, int(value)) - } - - // Check for a high surrogate area. - if value&0xFC00 == 0xD800 { - width = 4 - - // Check for incomplete surrogate pair. - if raw_unread < 4 { - if parser.eof { - return yaml_parser_set_reader_error(parser, - "incomplete UTF-16 surrogate pair", - parser.offset, -1) - } - break inner - } - - // Get the next character. - value2 := rune(parser.raw_buffer[parser.raw_buffer_pos+low+2]) + - (rune(parser.raw_buffer[parser.raw_buffer_pos+high+2]) << 8) - - // Check for a low surrogate area. - if value2&0xFC00 != 0xDC00 { - return yaml_parser_set_reader_error(parser, - "expected low surrogate area", - parser.offset+2, int(value2)) - } - - // Generate the value of the surrogate pair. - value = 0x10000 + ((value & 0x3FF) << 10) + (value2 & 0x3FF) - } else { - width = 2 - } - - default: - panic("impossible") - } - - // Check if the character is in the allowed range: - // #x9 | #xA | #xD | [#x20-#x7E] (8 bit) - // | #x85 | [#xA0-#xD7FF] | [#xE000-#xFFFD] (16 bit) - // | [#x10000-#x10FFFF] (32 bit) - switch { - case value == 0x09: - case value == 0x0A: - case value == 0x0D: - case value >= 0x20 && value <= 0x7E: - case value == 0x85: - case value >= 0xA0 && value <= 0xD7FF: - case value >= 0xE000 && value <= 0xFFFD: - case value >= 0x10000 && value <= 0x10FFFF: - default: - return yaml_parser_set_reader_error(parser, - "control characters are not allowed", - parser.offset, int(value)) - } - - // Move the raw pointers. - parser.raw_buffer_pos += width - parser.offset += width - - // Finally put the character into the buffer. - if value <= 0x7F { - // 0000 0000-0000 007F . 0xxxxxxx - parser.buffer[buffer_len+0] = byte(value) - buffer_len += 1 - } else if value <= 0x7FF { - // 0000 0080-0000 07FF . 110xxxxx 10xxxxxx - parser.buffer[buffer_len+0] = byte(0xC0 + (value >> 6)) - parser.buffer[buffer_len+1] = byte(0x80 + (value & 0x3F)) - buffer_len += 2 - } else if value <= 0xFFFF { - // 0000 0800-0000 FFFF . 1110xxxx 10xxxxxx 10xxxxxx - parser.buffer[buffer_len+0] = byte(0xE0 + (value >> 12)) - parser.buffer[buffer_len+1] = byte(0x80 + ((value >> 6) & 0x3F)) - parser.buffer[buffer_len+2] = byte(0x80 + (value & 0x3F)) - buffer_len += 3 - } else { - // 0001 0000-0010 FFFF . 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx - parser.buffer[buffer_len+0] = byte(0xF0 + (value >> 18)) - parser.buffer[buffer_len+1] = byte(0x80 + ((value >> 12) & 0x3F)) - parser.buffer[buffer_len+2] = byte(0x80 + ((value >> 6) & 0x3F)) - parser.buffer[buffer_len+3] = byte(0x80 + (value & 0x3F)) - buffer_len += 4 - } - - parser.unread++ - } - - // On EOF, put NUL into the buffer and return. - if parser.eof { - parser.buffer[buffer_len] = 0 - buffer_len++ - parser.unread++ - break - } - } - // [Go] Read the documentation of this function above. To return true, - // we need to have the given length in the buffer. Not doing that means - // every single check that calls this function to make sure the buffer - // has a given length is Go) panicking; or C) accessing invalid memory. - // This happens here due to the EOF above breaking early. - for buffer_len < length { - parser.buffer[buffer_len] = 0 - buffer_len++ - } - parser.buffer = parser.buffer[:buffer_len] - return true -} diff --git a/vendor/gopkg.in/yaml.v2/resolve.go b/vendor/gopkg.in/yaml.v2/resolve.go deleted file mode 100644 index 4120e0c916..0000000000 --- a/vendor/gopkg.in/yaml.v2/resolve.go +++ /dev/null @@ -1,258 +0,0 @@ -package yaml - -import ( - "encoding/base64" - "math" - "regexp" - "strconv" - "strings" - "time" -) - -type resolveMapItem struct { - value interface{} - tag string -} - -var resolveTable = make([]byte, 256) -var resolveMap = make(map[string]resolveMapItem) - -func init() { - t := resolveTable - t[int('+')] = 'S' // Sign - t[int('-')] = 'S' - for _, c := range "0123456789" { - t[int(c)] = 'D' // Digit - } - for _, c := range "yYnNtTfFoO~" { - t[int(c)] = 'M' // In map - } - t[int('.')] = '.' // Float (potentially in map) - - var resolveMapList = []struct { - v interface{} - tag string - l []string - }{ - {true, yaml_BOOL_TAG, []string{"y", "Y", "yes", "Yes", "YES"}}, - {true, yaml_BOOL_TAG, []string{"true", "True", "TRUE"}}, - {true, yaml_BOOL_TAG, []string{"on", "On", "ON"}}, - {false, yaml_BOOL_TAG, []string{"n", "N", "no", "No", "NO"}}, - {false, yaml_BOOL_TAG, []string{"false", "False", "FALSE"}}, - {false, yaml_BOOL_TAG, []string{"off", "Off", "OFF"}}, - {nil, yaml_NULL_TAG, []string{"", "~", "null", "Null", "NULL"}}, - {math.NaN(), yaml_FLOAT_TAG, []string{".nan", ".NaN", ".NAN"}}, - {math.Inf(+1), yaml_FLOAT_TAG, []string{".inf", ".Inf", ".INF"}}, - {math.Inf(+1), yaml_FLOAT_TAG, []string{"+.inf", "+.Inf", "+.INF"}}, - {math.Inf(-1), yaml_FLOAT_TAG, []string{"-.inf", "-.Inf", "-.INF"}}, - {"<<", yaml_MERGE_TAG, []string{"<<"}}, - } - - m := resolveMap - for _, item := range resolveMapList { - for _, s := range item.l { - m[s] = resolveMapItem{item.v, item.tag} - } - } -} - -const longTagPrefix = "tag:yaml.org,2002:" - -func shortTag(tag string) string { - // TODO This can easily be made faster and produce less garbage. - if strings.HasPrefix(tag, longTagPrefix) { - return "!!" + tag[len(longTagPrefix):] - } - return tag -} - -func longTag(tag string) string { - if strings.HasPrefix(tag, "!!") { - return longTagPrefix + tag[2:] - } - return tag -} - -func resolvableTag(tag string) bool { - switch tag { - case "", yaml_STR_TAG, yaml_BOOL_TAG, yaml_INT_TAG, yaml_FLOAT_TAG, yaml_NULL_TAG, yaml_TIMESTAMP_TAG: - return true - } - return false -} - -var yamlStyleFloat = regexp.MustCompile(`^[-+]?(\.[0-9]+|[0-9]+(\.[0-9]*)?)([eE][-+]?[0-9]+)?$`) - -func resolve(tag string, in string) (rtag string, out interface{}) { - if !resolvableTag(tag) { - return tag, in - } - - defer func() { - switch tag { - case "", rtag, yaml_STR_TAG, yaml_BINARY_TAG: - return - case yaml_FLOAT_TAG: - if rtag == yaml_INT_TAG { - switch v := out.(type) { - case int64: - rtag = yaml_FLOAT_TAG - out = float64(v) - return - case int: - rtag = yaml_FLOAT_TAG - out = float64(v) - return - } - } - } - failf("cannot decode %s `%s` as a %s", shortTag(rtag), in, shortTag(tag)) - }() - - // Any data is accepted as a !!str or !!binary. - // Otherwise, the prefix is enough of a hint about what it might be. - hint := byte('N') - if in != "" { - hint = resolveTable[in[0]] - } - if hint != 0 && tag != yaml_STR_TAG && tag != yaml_BINARY_TAG { - // Handle things we can lookup in a map. - if item, ok := resolveMap[in]; ok { - return item.tag, item.value - } - - // Base 60 floats are a bad idea, were dropped in YAML 1.2, and - // are purposefully unsupported here. They're still quoted on - // the way out for compatibility with other parser, though. - - switch hint { - case 'M': - // We've already checked the map above. - - case '.': - // Not in the map, so maybe a normal float. - floatv, err := strconv.ParseFloat(in, 64) - if err == nil { - return yaml_FLOAT_TAG, floatv - } - - case 'D', 'S': - // Int, float, or timestamp. - // Only try values as a timestamp if the value is unquoted or there's an explicit - // !!timestamp tag. - if tag == "" || tag == yaml_TIMESTAMP_TAG { - t, ok := parseTimestamp(in) - if ok { - return yaml_TIMESTAMP_TAG, t - } - } - - plain := strings.Replace(in, "_", "", -1) - intv, err := strconv.ParseInt(plain, 0, 64) - if err == nil { - if intv == int64(int(intv)) { - return yaml_INT_TAG, int(intv) - } else { - return yaml_INT_TAG, intv - } - } - uintv, err := strconv.ParseUint(plain, 0, 64) - if err == nil { - return yaml_INT_TAG, uintv - } - if yamlStyleFloat.MatchString(plain) { - floatv, err := strconv.ParseFloat(plain, 64) - if err == nil { - return yaml_FLOAT_TAG, floatv - } - } - if strings.HasPrefix(plain, "0b") { - intv, err := strconv.ParseInt(plain[2:], 2, 64) - if err == nil { - if intv == int64(int(intv)) { - return yaml_INT_TAG, int(intv) - } else { - return yaml_INT_TAG, intv - } - } - uintv, err := strconv.ParseUint(plain[2:], 2, 64) - if err == nil { - return yaml_INT_TAG, uintv - } - } else if strings.HasPrefix(plain, "-0b") { - intv, err := strconv.ParseInt("-" + plain[3:], 2, 64) - if err == nil { - if true || intv == int64(int(intv)) { - return yaml_INT_TAG, int(intv) - } else { - return yaml_INT_TAG, intv - } - } - } - default: - panic("resolveTable item not yet handled: " + string(rune(hint)) + " (with " + in + ")") - } - } - return yaml_STR_TAG, in -} - -// encodeBase64 encodes s as base64 that is broken up into multiple lines -// as appropriate for the resulting length. -func encodeBase64(s string) string { - const lineLen = 70 - encLen := base64.StdEncoding.EncodedLen(len(s)) - lines := encLen/lineLen + 1 - buf := make([]byte, encLen*2+lines) - in := buf[0:encLen] - out := buf[encLen:] - base64.StdEncoding.Encode(in, []byte(s)) - k := 0 - for i := 0; i < len(in); i += lineLen { - j := i + lineLen - if j > len(in) { - j = len(in) - } - k += copy(out[k:], in[i:j]) - if lines > 1 { - out[k] = '\n' - k++ - } - } - return string(out[:k]) -} - -// This is a subset of the formats allowed by the regular expression -// defined at http://yaml.org/type/timestamp.html. -var allowedTimestampFormats = []string{ - "2006-1-2T15:4:5.999999999Z07:00", // RCF3339Nano with short date fields. - "2006-1-2t15:4:5.999999999Z07:00", // RFC3339Nano with short date fields and lower-case "t". - "2006-1-2 15:4:5.999999999", // space separated with no time zone - "2006-1-2", // date only - // Notable exception: time.Parse cannot handle: "2001-12-14 21:59:43.10 -5" - // from the set of examples. -} - -// parseTimestamp parses s as a timestamp string and -// returns the timestamp and reports whether it succeeded. -// Timestamp formats are defined at http://yaml.org/type/timestamp.html -func parseTimestamp(s string) (time.Time, bool) { - // TODO write code to check all the formats supported by - // http://yaml.org/type/timestamp.html instead of using time.Parse. - - // Quick check: all date formats start with YYYY-. - i := 0 - for ; i < len(s); i++ { - if c := s[i]; c < '0' || c > '9' { - break - } - } - if i != 4 || i == len(s) || s[i] != '-' { - return time.Time{}, false - } - for _, format := range allowedTimestampFormats { - if t, err := time.Parse(format, s); err == nil { - return t, true - } - } - return time.Time{}, false -} diff --git a/vendor/gopkg.in/yaml.v2/scannerc.go b/vendor/gopkg.in/yaml.v2/scannerc.go deleted file mode 100644 index 0b9bb6030a..0000000000 --- a/vendor/gopkg.in/yaml.v2/scannerc.go +++ /dev/null @@ -1,2711 +0,0 @@ -package yaml - -import ( - "bytes" - "fmt" -) - -// Introduction -// ************ -// -// The following notes assume that you are familiar with the YAML specification -// (http://yaml.org/spec/1.2/spec.html). We mostly follow it, although in -// some cases we are less restrictive that it requires. -// -// The process of transforming a YAML stream into a sequence of events is -// divided on two steps: Scanning and Parsing. -// -// The Scanner transforms the input stream into a sequence of tokens, while the -// parser transform the sequence of tokens produced by the Scanner into a -// sequence of parsing events. -// -// The Scanner is rather clever and complicated. The Parser, on the contrary, -// is a straightforward implementation of a recursive-descendant parser (or, -// LL(1) parser, as it is usually called). -// -// Actually there are two issues of Scanning that might be called "clever", the -// rest is quite straightforward. The issues are "block collection start" and -// "simple keys". Both issues are explained below in details. -// -// Here the Scanning step is explained and implemented. We start with the list -// of all the tokens produced by the Scanner together with short descriptions. -// -// Now, tokens: -// -// STREAM-START(encoding) # The stream start. -// STREAM-END # The stream end. -// VERSION-DIRECTIVE(major,minor) # The '%YAML' directive. -// TAG-DIRECTIVE(handle,prefix) # The '%TAG' directive. -// DOCUMENT-START # '---' -// DOCUMENT-END # '...' -// BLOCK-SEQUENCE-START # Indentation increase denoting a block -// BLOCK-MAPPING-START # sequence or a block mapping. -// BLOCK-END # Indentation decrease. -// FLOW-SEQUENCE-START # '[' -// FLOW-SEQUENCE-END # ']' -// BLOCK-SEQUENCE-START # '{' -// BLOCK-SEQUENCE-END # '}' -// BLOCK-ENTRY # '-' -// FLOW-ENTRY # ',' -// KEY # '?' or nothing (simple keys). -// VALUE # ':' -// ALIAS(anchor) # '*anchor' -// ANCHOR(anchor) # '&anchor' -// TAG(handle,suffix) # '!handle!suffix' -// SCALAR(value,style) # A scalar. -// -// The following two tokens are "virtual" tokens denoting the beginning and the -// end of the stream: -// -// STREAM-START(encoding) -// STREAM-END -// -// We pass the information about the input stream encoding with the -// STREAM-START token. -// -// The next two tokens are responsible for tags: -// -// VERSION-DIRECTIVE(major,minor) -// TAG-DIRECTIVE(handle,prefix) -// -// Example: -// -// %YAML 1.1 -// %TAG ! !foo -// %TAG !yaml! tag:yaml.org,2002: -// --- -// -// The correspoding sequence of tokens: -// -// STREAM-START(utf-8) -// VERSION-DIRECTIVE(1,1) -// TAG-DIRECTIVE("!","!foo") -// TAG-DIRECTIVE("!yaml","tag:yaml.org,2002:") -// DOCUMENT-START -// STREAM-END -// -// Note that the VERSION-DIRECTIVE and TAG-DIRECTIVE tokens occupy a whole -// line. -// -// The document start and end indicators are represented by: -// -// DOCUMENT-START -// DOCUMENT-END -// -// Note that if a YAML stream contains an implicit document (without '---' -// and '...' indicators), no DOCUMENT-START and DOCUMENT-END tokens will be -// produced. -// -// In the following examples, we present whole documents together with the -// produced tokens. -// -// 1. An implicit document: -// -// 'a scalar' -// -// Tokens: -// -// STREAM-START(utf-8) -// SCALAR("a scalar",single-quoted) -// STREAM-END -// -// 2. An explicit document: -// -// --- -// 'a scalar' -// ... -// -// Tokens: -// -// STREAM-START(utf-8) -// DOCUMENT-START -// SCALAR("a scalar",single-quoted) -// DOCUMENT-END -// STREAM-END -// -// 3. Several documents in a stream: -// -// 'a scalar' -// --- -// 'another scalar' -// --- -// 'yet another scalar' -// -// Tokens: -// -// STREAM-START(utf-8) -// SCALAR("a scalar",single-quoted) -// DOCUMENT-START -// SCALAR("another scalar",single-quoted) -// DOCUMENT-START -// SCALAR("yet another scalar",single-quoted) -// STREAM-END -// -// We have already introduced the SCALAR token above. The following tokens are -// used to describe aliases, anchors, tag, and scalars: -// -// ALIAS(anchor) -// ANCHOR(anchor) -// TAG(handle,suffix) -// SCALAR(value,style) -// -// The following series of examples illustrate the usage of these tokens: -// -// 1. A recursive sequence: -// -// &A [ *A ] -// -// Tokens: -// -// STREAM-START(utf-8) -// ANCHOR("A") -// FLOW-SEQUENCE-START -// ALIAS("A") -// FLOW-SEQUENCE-END -// STREAM-END -// -// 2. A tagged scalar: -// -// !!float "3.14" # A good approximation. -// -// Tokens: -// -// STREAM-START(utf-8) -// TAG("!!","float") -// SCALAR("3.14",double-quoted) -// STREAM-END -// -// 3. Various scalar styles: -// -// --- # Implicit empty plain scalars do not produce tokens. -// --- a plain scalar -// --- 'a single-quoted scalar' -// --- "a double-quoted scalar" -// --- |- -// a literal scalar -// --- >- -// a folded -// scalar -// -// Tokens: -// -// STREAM-START(utf-8) -// DOCUMENT-START -// DOCUMENT-START -// SCALAR("a plain scalar",plain) -// DOCUMENT-START -// SCALAR("a single-quoted scalar",single-quoted) -// DOCUMENT-START -// SCALAR("a double-quoted scalar",double-quoted) -// DOCUMENT-START -// SCALAR("a literal scalar",literal) -// DOCUMENT-START -// SCALAR("a folded scalar",folded) -// STREAM-END -// -// Now it's time to review collection-related tokens. We will start with -// flow collections: -// -// FLOW-SEQUENCE-START -// FLOW-SEQUENCE-END -// FLOW-MAPPING-START -// FLOW-MAPPING-END -// FLOW-ENTRY -// KEY -// VALUE -// -// The tokens FLOW-SEQUENCE-START, FLOW-SEQUENCE-END, FLOW-MAPPING-START, and -// FLOW-MAPPING-END represent the indicators '[', ']', '{', and '}' -// correspondingly. FLOW-ENTRY represent the ',' indicator. Finally the -// indicators '?' and ':', which are used for denoting mapping keys and values, -// are represented by the KEY and VALUE tokens. -// -// The following examples show flow collections: -// -// 1. A flow sequence: -// -// [item 1, item 2, item 3] -// -// Tokens: -// -// STREAM-START(utf-8) -// FLOW-SEQUENCE-START -// SCALAR("item 1",plain) -// FLOW-ENTRY -// SCALAR("item 2",plain) -// FLOW-ENTRY -// SCALAR("item 3",plain) -// FLOW-SEQUENCE-END -// STREAM-END -// -// 2. A flow mapping: -// -// { -// a simple key: a value, # Note that the KEY token is produced. -// ? a complex key: another value, -// } -// -// Tokens: -// -// STREAM-START(utf-8) -// FLOW-MAPPING-START -// KEY -// SCALAR("a simple key",plain) -// VALUE -// SCALAR("a value",plain) -// FLOW-ENTRY -// KEY -// SCALAR("a complex key",plain) -// VALUE -// SCALAR("another value",plain) -// FLOW-ENTRY -// FLOW-MAPPING-END -// STREAM-END -// -// A simple key is a key which is not denoted by the '?' indicator. Note that -// the Scanner still produce the KEY token whenever it encounters a simple key. -// -// For scanning block collections, the following tokens are used (note that we -// repeat KEY and VALUE here): -// -// BLOCK-SEQUENCE-START -// BLOCK-MAPPING-START -// BLOCK-END -// BLOCK-ENTRY -// KEY -// VALUE -// -// The tokens BLOCK-SEQUENCE-START and BLOCK-MAPPING-START denote indentation -// increase that precedes a block collection (cf. the INDENT token in Python). -// The token BLOCK-END denote indentation decrease that ends a block collection -// (cf. the DEDENT token in Python). However YAML has some syntax pecularities -// that makes detections of these tokens more complex. -// -// The tokens BLOCK-ENTRY, KEY, and VALUE are used to represent the indicators -// '-', '?', and ':' correspondingly. -// -// The following examples show how the tokens BLOCK-SEQUENCE-START, -// BLOCK-MAPPING-START, and BLOCK-END are emitted by the Scanner: -// -// 1. Block sequences: -// -// - item 1 -// - item 2 -// - -// - item 3.1 -// - item 3.2 -// - -// key 1: value 1 -// key 2: value 2 -// -// Tokens: -// -// STREAM-START(utf-8) -// BLOCK-SEQUENCE-START -// BLOCK-ENTRY -// SCALAR("item 1",plain) -// BLOCK-ENTRY -// SCALAR("item 2",plain) -// BLOCK-ENTRY -// BLOCK-SEQUENCE-START -// BLOCK-ENTRY -// SCALAR("item 3.1",plain) -// BLOCK-ENTRY -// SCALAR("item 3.2",plain) -// BLOCK-END -// BLOCK-ENTRY -// BLOCK-MAPPING-START -// KEY -// SCALAR("key 1",plain) -// VALUE -// SCALAR("value 1",plain) -// KEY -// SCALAR("key 2",plain) -// VALUE -// SCALAR("value 2",plain) -// BLOCK-END -// BLOCK-END -// STREAM-END -// -// 2. Block mappings: -// -// a simple key: a value # The KEY token is produced here. -// ? a complex key -// : another value -// a mapping: -// key 1: value 1 -// key 2: value 2 -// a sequence: -// - item 1 -// - item 2 -// -// Tokens: -// -// STREAM-START(utf-8) -// BLOCK-MAPPING-START -// KEY -// SCALAR("a simple key",plain) -// VALUE -// SCALAR("a value",plain) -// KEY -// SCALAR("a complex key",plain) -// VALUE -// SCALAR("another value",plain) -// KEY -// SCALAR("a mapping",plain) -// BLOCK-MAPPING-START -// KEY -// SCALAR("key 1",plain) -// VALUE -// SCALAR("value 1",plain) -// KEY -// SCALAR("key 2",plain) -// VALUE -// SCALAR("value 2",plain) -// BLOCK-END -// KEY -// SCALAR("a sequence",plain) -// VALUE -// BLOCK-SEQUENCE-START -// BLOCK-ENTRY -// SCALAR("item 1",plain) -// BLOCK-ENTRY -// SCALAR("item 2",plain) -// BLOCK-END -// BLOCK-END -// STREAM-END -// -// YAML does not always require to start a new block collection from a new -// line. If the current line contains only '-', '?', and ':' indicators, a new -// block collection may start at the current line. The following examples -// illustrate this case: -// -// 1. Collections in a sequence: -// -// - - item 1 -// - item 2 -// - key 1: value 1 -// key 2: value 2 -// - ? complex key -// : complex value -// -// Tokens: -// -// STREAM-START(utf-8) -// BLOCK-SEQUENCE-START -// BLOCK-ENTRY -// BLOCK-SEQUENCE-START -// BLOCK-ENTRY -// SCALAR("item 1",plain) -// BLOCK-ENTRY -// SCALAR("item 2",plain) -// BLOCK-END -// BLOCK-ENTRY -// BLOCK-MAPPING-START -// KEY -// SCALAR("key 1",plain) -// VALUE -// SCALAR("value 1",plain) -// KEY -// SCALAR("key 2",plain) -// VALUE -// SCALAR("value 2",plain) -// BLOCK-END -// BLOCK-ENTRY -// BLOCK-MAPPING-START -// KEY -// SCALAR("complex key") -// VALUE -// SCALAR("complex value") -// BLOCK-END -// BLOCK-END -// STREAM-END -// -// 2. Collections in a mapping: -// -// ? a sequence -// : - item 1 -// - item 2 -// ? a mapping -// : key 1: value 1 -// key 2: value 2 -// -// Tokens: -// -// STREAM-START(utf-8) -// BLOCK-MAPPING-START -// KEY -// SCALAR("a sequence",plain) -// VALUE -// BLOCK-SEQUENCE-START -// BLOCK-ENTRY -// SCALAR("item 1",plain) -// BLOCK-ENTRY -// SCALAR("item 2",plain) -// BLOCK-END -// KEY -// SCALAR("a mapping",plain) -// VALUE -// BLOCK-MAPPING-START -// KEY -// SCALAR("key 1",plain) -// VALUE -// SCALAR("value 1",plain) -// KEY -// SCALAR("key 2",plain) -// VALUE -// SCALAR("value 2",plain) -// BLOCK-END -// BLOCK-END -// STREAM-END -// -// YAML also permits non-indented sequences if they are included into a block -// mapping. In this case, the token BLOCK-SEQUENCE-START is not produced: -// -// key: -// - item 1 # BLOCK-SEQUENCE-START is NOT produced here. -// - item 2 -// -// Tokens: -// -// STREAM-START(utf-8) -// BLOCK-MAPPING-START -// KEY -// SCALAR("key",plain) -// VALUE -// BLOCK-ENTRY -// SCALAR("item 1",plain) -// BLOCK-ENTRY -// SCALAR("item 2",plain) -// BLOCK-END -// - -// Ensure that the buffer contains the required number of characters. -// Return true on success, false on failure (reader error or memory error). -func cache(parser *yaml_parser_t, length int) bool { - // [Go] This was inlined: !cache(A, B) -> unread < B && !update(A, B) - return parser.unread >= length || yaml_parser_update_buffer(parser, length) -} - -// Advance the buffer pointer. -func skip(parser *yaml_parser_t) { - parser.mark.index++ - parser.mark.column++ - parser.unread-- - parser.buffer_pos += width(parser.buffer[parser.buffer_pos]) -} - -func skip_line(parser *yaml_parser_t) { - if is_crlf(parser.buffer, parser.buffer_pos) { - parser.mark.index += 2 - parser.mark.column = 0 - parser.mark.line++ - parser.unread -= 2 - parser.buffer_pos += 2 - } else if is_break(parser.buffer, parser.buffer_pos) { - parser.mark.index++ - parser.mark.column = 0 - parser.mark.line++ - parser.unread-- - parser.buffer_pos += width(parser.buffer[parser.buffer_pos]) - } -} - -// Copy a character to a string buffer and advance pointers. -func read(parser *yaml_parser_t, s []byte) []byte { - w := width(parser.buffer[parser.buffer_pos]) - if w == 0 { - panic("invalid character sequence") - } - if len(s) == 0 { - s = make([]byte, 0, 32) - } - if w == 1 && len(s)+w <= cap(s) { - s = s[:len(s)+1] - s[len(s)-1] = parser.buffer[parser.buffer_pos] - parser.buffer_pos++ - } else { - s = append(s, parser.buffer[parser.buffer_pos:parser.buffer_pos+w]...) - parser.buffer_pos += w - } - parser.mark.index++ - parser.mark.column++ - parser.unread-- - return s -} - -// Copy a line break character to a string buffer and advance pointers. -func read_line(parser *yaml_parser_t, s []byte) []byte { - buf := parser.buffer - pos := parser.buffer_pos - switch { - case buf[pos] == '\r' && buf[pos+1] == '\n': - // CR LF . LF - s = append(s, '\n') - parser.buffer_pos += 2 - parser.mark.index++ - parser.unread-- - case buf[pos] == '\r' || buf[pos] == '\n': - // CR|LF . LF - s = append(s, '\n') - parser.buffer_pos += 1 - case buf[pos] == '\xC2' && buf[pos+1] == '\x85': - // NEL . LF - s = append(s, '\n') - parser.buffer_pos += 2 - case buf[pos] == '\xE2' && buf[pos+1] == '\x80' && (buf[pos+2] == '\xA8' || buf[pos+2] == '\xA9'): - // LS|PS . LS|PS - s = append(s, buf[parser.buffer_pos:pos+3]...) - parser.buffer_pos += 3 - default: - return s - } - parser.mark.index++ - parser.mark.column = 0 - parser.mark.line++ - parser.unread-- - return s -} - -// Get the next token. -func yaml_parser_scan(parser *yaml_parser_t, token *yaml_token_t) bool { - // Erase the token object. - *token = yaml_token_t{} // [Go] Is this necessary? - - // No tokens after STREAM-END or error. - if parser.stream_end_produced || parser.error != yaml_NO_ERROR { - return true - } - - // Ensure that the tokens queue contains enough tokens. - if !parser.token_available { - if !yaml_parser_fetch_more_tokens(parser) { - return false - } - } - - // Fetch the next token from the queue. - *token = parser.tokens[parser.tokens_head] - parser.tokens_head++ - parser.tokens_parsed++ - parser.token_available = false - - if token.typ == yaml_STREAM_END_TOKEN { - parser.stream_end_produced = true - } - return true -} - -// Set the scanner error and return false. -func yaml_parser_set_scanner_error(parser *yaml_parser_t, context string, context_mark yaml_mark_t, problem string) bool { - parser.error = yaml_SCANNER_ERROR - parser.context = context - parser.context_mark = context_mark - parser.problem = problem - parser.problem_mark = parser.mark - return false -} - -func yaml_parser_set_scanner_tag_error(parser *yaml_parser_t, directive bool, context_mark yaml_mark_t, problem string) bool { - context := "while parsing a tag" - if directive { - context = "while parsing a %TAG directive" - } - return yaml_parser_set_scanner_error(parser, context, context_mark, problem) -} - -func trace(args ...interface{}) func() { - pargs := append([]interface{}{"+++"}, args...) - fmt.Println(pargs...) - pargs = append([]interface{}{"---"}, args...) - return func() { fmt.Println(pargs...) } -} - -// Ensure that the tokens queue contains at least one token which can be -// returned to the Parser. -func yaml_parser_fetch_more_tokens(parser *yaml_parser_t) bool { - // While we need more tokens to fetch, do it. - for { - if parser.tokens_head != len(parser.tokens) { - // If queue is non-empty, check if any potential simple key may - // occupy the head position. - head_tok_idx, ok := parser.simple_keys_by_tok[parser.tokens_parsed] - if !ok { - break - } else if valid, ok := yaml_simple_key_is_valid(parser, &parser.simple_keys[head_tok_idx]); !ok { - return false - } else if !valid { - break - } - } - // Fetch the next token. - if !yaml_parser_fetch_next_token(parser) { - return false - } - } - - parser.token_available = true - return true -} - -// The dispatcher for token fetchers. -func yaml_parser_fetch_next_token(parser *yaml_parser_t) bool { - // Ensure that the buffer is initialized. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - - // Check if we just started scanning. Fetch STREAM-START then. - if !parser.stream_start_produced { - return yaml_parser_fetch_stream_start(parser) - } - - // Eat whitespaces and comments until we reach the next token. - if !yaml_parser_scan_to_next_token(parser) { - return false - } - - // Check the indentation level against the current column. - if !yaml_parser_unroll_indent(parser, parser.mark.column) { - return false - } - - // Ensure that the buffer contains at least 4 characters. 4 is the length - // of the longest indicators ('--- ' and '... '). - if parser.unread < 4 && !yaml_parser_update_buffer(parser, 4) { - return false - } - - // Is it the end of the stream? - if is_z(parser.buffer, parser.buffer_pos) { - return yaml_parser_fetch_stream_end(parser) - } - - // Is it a directive? - if parser.mark.column == 0 && parser.buffer[parser.buffer_pos] == '%' { - return yaml_parser_fetch_directive(parser) - } - - buf := parser.buffer - pos := parser.buffer_pos - - // Is it the document start indicator? - if parser.mark.column == 0 && buf[pos] == '-' && buf[pos+1] == '-' && buf[pos+2] == '-' && is_blankz(buf, pos+3) { - return yaml_parser_fetch_document_indicator(parser, yaml_DOCUMENT_START_TOKEN) - } - - // Is it the document end indicator? - if parser.mark.column == 0 && buf[pos] == '.' && buf[pos+1] == '.' && buf[pos+2] == '.' && is_blankz(buf, pos+3) { - return yaml_parser_fetch_document_indicator(parser, yaml_DOCUMENT_END_TOKEN) - } - - // Is it the flow sequence start indicator? - if buf[pos] == '[' { - return yaml_parser_fetch_flow_collection_start(parser, yaml_FLOW_SEQUENCE_START_TOKEN) - } - - // Is it the flow mapping start indicator? - if parser.buffer[parser.buffer_pos] == '{' { - return yaml_parser_fetch_flow_collection_start(parser, yaml_FLOW_MAPPING_START_TOKEN) - } - - // Is it the flow sequence end indicator? - if parser.buffer[parser.buffer_pos] == ']' { - return yaml_parser_fetch_flow_collection_end(parser, - yaml_FLOW_SEQUENCE_END_TOKEN) - } - - // Is it the flow mapping end indicator? - if parser.buffer[parser.buffer_pos] == '}' { - return yaml_parser_fetch_flow_collection_end(parser, - yaml_FLOW_MAPPING_END_TOKEN) - } - - // Is it the flow entry indicator? - if parser.buffer[parser.buffer_pos] == ',' { - return yaml_parser_fetch_flow_entry(parser) - } - - // Is it the block entry indicator? - if parser.buffer[parser.buffer_pos] == '-' && is_blankz(parser.buffer, parser.buffer_pos+1) { - return yaml_parser_fetch_block_entry(parser) - } - - // Is it the key indicator? - if parser.buffer[parser.buffer_pos] == '?' && (parser.flow_level > 0 || is_blankz(parser.buffer, parser.buffer_pos+1)) { - return yaml_parser_fetch_key(parser) - } - - // Is it the value indicator? - if parser.buffer[parser.buffer_pos] == ':' && (parser.flow_level > 0 || is_blankz(parser.buffer, parser.buffer_pos+1)) { - return yaml_parser_fetch_value(parser) - } - - // Is it an alias? - if parser.buffer[parser.buffer_pos] == '*' { - return yaml_parser_fetch_anchor(parser, yaml_ALIAS_TOKEN) - } - - // Is it an anchor? - if parser.buffer[parser.buffer_pos] == '&' { - return yaml_parser_fetch_anchor(parser, yaml_ANCHOR_TOKEN) - } - - // Is it a tag? - if parser.buffer[parser.buffer_pos] == '!' { - return yaml_parser_fetch_tag(parser) - } - - // Is it a literal scalar? - if parser.buffer[parser.buffer_pos] == '|' && parser.flow_level == 0 { - return yaml_parser_fetch_block_scalar(parser, true) - } - - // Is it a folded scalar? - if parser.buffer[parser.buffer_pos] == '>' && parser.flow_level == 0 { - return yaml_parser_fetch_block_scalar(parser, false) - } - - // Is it a single-quoted scalar? - if parser.buffer[parser.buffer_pos] == '\'' { - return yaml_parser_fetch_flow_scalar(parser, true) - } - - // Is it a double-quoted scalar? - if parser.buffer[parser.buffer_pos] == '"' { - return yaml_parser_fetch_flow_scalar(parser, false) - } - - // Is it a plain scalar? - // - // A plain scalar may start with any non-blank characters except - // - // '-', '?', ':', ',', '[', ']', '{', '}', - // '#', '&', '*', '!', '|', '>', '\'', '\"', - // '%', '@', '`'. - // - // In the block context (and, for the '-' indicator, in the flow context - // too), it may also start with the characters - // - // '-', '?', ':' - // - // if it is followed by a non-space character. - // - // The last rule is more restrictive than the specification requires. - // [Go] Make this logic more reasonable. - //switch parser.buffer[parser.buffer_pos] { - //case '-', '?', ':', ',', '?', '-', ',', ':', ']', '[', '}', '{', '&', '#', '!', '*', '>', '|', '"', '\'', '@', '%', '-', '`': - //} - if !(is_blankz(parser.buffer, parser.buffer_pos) || parser.buffer[parser.buffer_pos] == '-' || - parser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == ':' || - parser.buffer[parser.buffer_pos] == ',' || parser.buffer[parser.buffer_pos] == '[' || - parser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '{' || - parser.buffer[parser.buffer_pos] == '}' || parser.buffer[parser.buffer_pos] == '#' || - parser.buffer[parser.buffer_pos] == '&' || parser.buffer[parser.buffer_pos] == '*' || - parser.buffer[parser.buffer_pos] == '!' || parser.buffer[parser.buffer_pos] == '|' || - parser.buffer[parser.buffer_pos] == '>' || parser.buffer[parser.buffer_pos] == '\'' || - parser.buffer[parser.buffer_pos] == '"' || parser.buffer[parser.buffer_pos] == '%' || - parser.buffer[parser.buffer_pos] == '@' || parser.buffer[parser.buffer_pos] == '`') || - (parser.buffer[parser.buffer_pos] == '-' && !is_blank(parser.buffer, parser.buffer_pos+1)) || - (parser.flow_level == 0 && - (parser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == ':') && - !is_blankz(parser.buffer, parser.buffer_pos+1)) { - return yaml_parser_fetch_plain_scalar(parser) - } - - // If we don't determine the token type so far, it is an error. - return yaml_parser_set_scanner_error(parser, - "while scanning for the next token", parser.mark, - "found character that cannot start any token") -} - -func yaml_simple_key_is_valid(parser *yaml_parser_t, simple_key *yaml_simple_key_t) (valid, ok bool) { - if !simple_key.possible { - return false, true - } - - // The 1.2 specification says: - // - // "If the ? indicator is omitted, parsing needs to see past the - // implicit key to recognize it as such. To limit the amount of - // lookahead required, the “:” indicator must appear at most 1024 - // Unicode characters beyond the start of the key. In addition, the key - // is restricted to a single line." - // - if simple_key.mark.line < parser.mark.line || simple_key.mark.index+1024 < parser.mark.index { - // Check if the potential simple key to be removed is required. - if simple_key.required { - return false, yaml_parser_set_scanner_error(parser, - "while scanning a simple key", simple_key.mark, - "could not find expected ':'") - } - simple_key.possible = false - return false, true - } - return true, true -} - -// Check if a simple key may start at the current position and add it if -// needed. -func yaml_parser_save_simple_key(parser *yaml_parser_t) bool { - // A simple key is required at the current position if the scanner is in - // the block context and the current column coincides with the indentation - // level. - - required := parser.flow_level == 0 && parser.indent == parser.mark.column - - // - // If the current position may start a simple key, save it. - // - if parser.simple_key_allowed { - simple_key := yaml_simple_key_t{ - possible: true, - required: required, - token_number: parser.tokens_parsed + (len(parser.tokens) - parser.tokens_head), - mark: parser.mark, - } - - if !yaml_parser_remove_simple_key(parser) { - return false - } - parser.simple_keys[len(parser.simple_keys)-1] = simple_key - parser.simple_keys_by_tok[simple_key.token_number] = len(parser.simple_keys) - 1 - } - return true -} - -// Remove a potential simple key at the current flow level. -func yaml_parser_remove_simple_key(parser *yaml_parser_t) bool { - i := len(parser.simple_keys) - 1 - if parser.simple_keys[i].possible { - // If the key is required, it is an error. - if parser.simple_keys[i].required { - return yaml_parser_set_scanner_error(parser, - "while scanning a simple key", parser.simple_keys[i].mark, - "could not find expected ':'") - } - // Remove the key from the stack. - parser.simple_keys[i].possible = false - delete(parser.simple_keys_by_tok, parser.simple_keys[i].token_number) - } - return true -} - -// max_flow_level limits the flow_level -const max_flow_level = 10000 - -// Increase the flow level and resize the simple key list if needed. -func yaml_parser_increase_flow_level(parser *yaml_parser_t) bool { - // Reset the simple key on the next level. - parser.simple_keys = append(parser.simple_keys, yaml_simple_key_t{ - possible: false, - required: false, - token_number: parser.tokens_parsed + (len(parser.tokens) - parser.tokens_head), - mark: parser.mark, - }) - - // Increase the flow level. - parser.flow_level++ - if parser.flow_level > max_flow_level { - return yaml_parser_set_scanner_error(parser, - "while increasing flow level", parser.simple_keys[len(parser.simple_keys)-1].mark, - fmt.Sprintf("exceeded max depth of %d", max_flow_level)) - } - return true -} - -// Decrease the flow level. -func yaml_parser_decrease_flow_level(parser *yaml_parser_t) bool { - if parser.flow_level > 0 { - parser.flow_level-- - last := len(parser.simple_keys) - 1 - delete(parser.simple_keys_by_tok, parser.simple_keys[last].token_number) - parser.simple_keys = parser.simple_keys[:last] - } - return true -} - -// max_indents limits the indents stack size -const max_indents = 10000 - -// Push the current indentation level to the stack and set the new level -// the current column is greater than the indentation level. In this case, -// append or insert the specified token into the token queue. -func yaml_parser_roll_indent(parser *yaml_parser_t, column, number int, typ yaml_token_type_t, mark yaml_mark_t) bool { - // In the flow context, do nothing. - if parser.flow_level > 0 { - return true - } - - if parser.indent < column { - // Push the current indentation level to the stack and set the new - // indentation level. - parser.indents = append(parser.indents, parser.indent) - parser.indent = column - if len(parser.indents) > max_indents { - return yaml_parser_set_scanner_error(parser, - "while increasing indent level", parser.simple_keys[len(parser.simple_keys)-1].mark, - fmt.Sprintf("exceeded max depth of %d", max_indents)) - } - - // Create a token and insert it into the queue. - token := yaml_token_t{ - typ: typ, - start_mark: mark, - end_mark: mark, - } - if number > -1 { - number -= parser.tokens_parsed - } - yaml_insert_token(parser, number, &token) - } - return true -} - -// Pop indentation levels from the indents stack until the current level -// becomes less or equal to the column. For each indentation level, append -// the BLOCK-END token. -func yaml_parser_unroll_indent(parser *yaml_parser_t, column int) bool { - // In the flow context, do nothing. - if parser.flow_level > 0 { - return true - } - - // Loop through the indentation levels in the stack. - for parser.indent > column { - // Create a token and append it to the queue. - token := yaml_token_t{ - typ: yaml_BLOCK_END_TOKEN, - start_mark: parser.mark, - end_mark: parser.mark, - } - yaml_insert_token(parser, -1, &token) - - // Pop the indentation level. - parser.indent = parser.indents[len(parser.indents)-1] - parser.indents = parser.indents[:len(parser.indents)-1] - } - return true -} - -// Initialize the scanner and produce the STREAM-START token. -func yaml_parser_fetch_stream_start(parser *yaml_parser_t) bool { - - // Set the initial indentation. - parser.indent = -1 - - // Initialize the simple key stack. - parser.simple_keys = append(parser.simple_keys, yaml_simple_key_t{}) - - parser.simple_keys_by_tok = make(map[int]int) - - // A simple key is allowed at the beginning of the stream. - parser.simple_key_allowed = true - - // We have started. - parser.stream_start_produced = true - - // Create the STREAM-START token and append it to the queue. - token := yaml_token_t{ - typ: yaml_STREAM_START_TOKEN, - start_mark: parser.mark, - end_mark: parser.mark, - encoding: parser.encoding, - } - yaml_insert_token(parser, -1, &token) - return true -} - -// Produce the STREAM-END token and shut down the scanner. -func yaml_parser_fetch_stream_end(parser *yaml_parser_t) bool { - - // Force new line. - if parser.mark.column != 0 { - parser.mark.column = 0 - parser.mark.line++ - } - - // Reset the indentation level. - if !yaml_parser_unroll_indent(parser, -1) { - return false - } - - // Reset simple keys. - if !yaml_parser_remove_simple_key(parser) { - return false - } - - parser.simple_key_allowed = false - - // Create the STREAM-END token and append it to the queue. - token := yaml_token_t{ - typ: yaml_STREAM_END_TOKEN, - start_mark: parser.mark, - end_mark: parser.mark, - } - yaml_insert_token(parser, -1, &token) - return true -} - -// Produce a VERSION-DIRECTIVE or TAG-DIRECTIVE token. -func yaml_parser_fetch_directive(parser *yaml_parser_t) bool { - // Reset the indentation level. - if !yaml_parser_unroll_indent(parser, -1) { - return false - } - - // Reset simple keys. - if !yaml_parser_remove_simple_key(parser) { - return false - } - - parser.simple_key_allowed = false - - // Create the YAML-DIRECTIVE or TAG-DIRECTIVE token. - token := yaml_token_t{} - if !yaml_parser_scan_directive(parser, &token) { - return false - } - // Append the token to the queue. - yaml_insert_token(parser, -1, &token) - return true -} - -// Produce the DOCUMENT-START or DOCUMENT-END token. -func yaml_parser_fetch_document_indicator(parser *yaml_parser_t, typ yaml_token_type_t) bool { - // Reset the indentation level. - if !yaml_parser_unroll_indent(parser, -1) { - return false - } - - // Reset simple keys. - if !yaml_parser_remove_simple_key(parser) { - return false - } - - parser.simple_key_allowed = false - - // Consume the token. - start_mark := parser.mark - - skip(parser) - skip(parser) - skip(parser) - - end_mark := parser.mark - - // Create the DOCUMENT-START or DOCUMENT-END token. - token := yaml_token_t{ - typ: typ, - start_mark: start_mark, - end_mark: end_mark, - } - // Append the token to the queue. - yaml_insert_token(parser, -1, &token) - return true -} - -// Produce the FLOW-SEQUENCE-START or FLOW-MAPPING-START token. -func yaml_parser_fetch_flow_collection_start(parser *yaml_parser_t, typ yaml_token_type_t) bool { - // The indicators '[' and '{' may start a simple key. - if !yaml_parser_save_simple_key(parser) { - return false - } - - // Increase the flow level. - if !yaml_parser_increase_flow_level(parser) { - return false - } - - // A simple key may follow the indicators '[' and '{'. - parser.simple_key_allowed = true - - // Consume the token. - start_mark := parser.mark - skip(parser) - end_mark := parser.mark - - // Create the FLOW-SEQUENCE-START of FLOW-MAPPING-START token. - token := yaml_token_t{ - typ: typ, - start_mark: start_mark, - end_mark: end_mark, - } - // Append the token to the queue. - yaml_insert_token(parser, -1, &token) - return true -} - -// Produce the FLOW-SEQUENCE-END or FLOW-MAPPING-END token. -func yaml_parser_fetch_flow_collection_end(parser *yaml_parser_t, typ yaml_token_type_t) bool { - // Reset any potential simple key on the current flow level. - if !yaml_parser_remove_simple_key(parser) { - return false - } - - // Decrease the flow level. - if !yaml_parser_decrease_flow_level(parser) { - return false - } - - // No simple keys after the indicators ']' and '}'. - parser.simple_key_allowed = false - - // Consume the token. - - start_mark := parser.mark - skip(parser) - end_mark := parser.mark - - // Create the FLOW-SEQUENCE-END of FLOW-MAPPING-END token. - token := yaml_token_t{ - typ: typ, - start_mark: start_mark, - end_mark: end_mark, - } - // Append the token to the queue. - yaml_insert_token(parser, -1, &token) - return true -} - -// Produce the FLOW-ENTRY token. -func yaml_parser_fetch_flow_entry(parser *yaml_parser_t) bool { - // Reset any potential simple keys on the current flow level. - if !yaml_parser_remove_simple_key(parser) { - return false - } - - // Simple keys are allowed after ','. - parser.simple_key_allowed = true - - // Consume the token. - start_mark := parser.mark - skip(parser) - end_mark := parser.mark - - // Create the FLOW-ENTRY token and append it to the queue. - token := yaml_token_t{ - typ: yaml_FLOW_ENTRY_TOKEN, - start_mark: start_mark, - end_mark: end_mark, - } - yaml_insert_token(parser, -1, &token) - return true -} - -// Produce the BLOCK-ENTRY token. -func yaml_parser_fetch_block_entry(parser *yaml_parser_t) bool { - // Check if the scanner is in the block context. - if parser.flow_level == 0 { - // Check if we are allowed to start a new entry. - if !parser.simple_key_allowed { - return yaml_parser_set_scanner_error(parser, "", parser.mark, - "block sequence entries are not allowed in this context") - } - // Add the BLOCK-SEQUENCE-START token if needed. - if !yaml_parser_roll_indent(parser, parser.mark.column, -1, yaml_BLOCK_SEQUENCE_START_TOKEN, parser.mark) { - return false - } - } else { - // It is an error for the '-' indicator to occur in the flow context, - // but we let the Parser detect and report about it because the Parser - // is able to point to the context. - } - - // Reset any potential simple keys on the current flow level. - if !yaml_parser_remove_simple_key(parser) { - return false - } - - // Simple keys are allowed after '-'. - parser.simple_key_allowed = true - - // Consume the token. - start_mark := parser.mark - skip(parser) - end_mark := parser.mark - - // Create the BLOCK-ENTRY token and append it to the queue. - token := yaml_token_t{ - typ: yaml_BLOCK_ENTRY_TOKEN, - start_mark: start_mark, - end_mark: end_mark, - } - yaml_insert_token(parser, -1, &token) - return true -} - -// Produce the KEY token. -func yaml_parser_fetch_key(parser *yaml_parser_t) bool { - - // In the block context, additional checks are required. - if parser.flow_level == 0 { - // Check if we are allowed to start a new key (not nessesary simple). - if !parser.simple_key_allowed { - return yaml_parser_set_scanner_error(parser, "", parser.mark, - "mapping keys are not allowed in this context") - } - // Add the BLOCK-MAPPING-START token if needed. - if !yaml_parser_roll_indent(parser, parser.mark.column, -1, yaml_BLOCK_MAPPING_START_TOKEN, parser.mark) { - return false - } - } - - // Reset any potential simple keys on the current flow level. - if !yaml_parser_remove_simple_key(parser) { - return false - } - - // Simple keys are allowed after '?' in the block context. - parser.simple_key_allowed = parser.flow_level == 0 - - // Consume the token. - start_mark := parser.mark - skip(parser) - end_mark := parser.mark - - // Create the KEY token and append it to the queue. - token := yaml_token_t{ - typ: yaml_KEY_TOKEN, - start_mark: start_mark, - end_mark: end_mark, - } - yaml_insert_token(parser, -1, &token) - return true -} - -// Produce the VALUE token. -func yaml_parser_fetch_value(parser *yaml_parser_t) bool { - - simple_key := &parser.simple_keys[len(parser.simple_keys)-1] - - // Have we found a simple key? - if valid, ok := yaml_simple_key_is_valid(parser, simple_key); !ok { - return false - - } else if valid { - - // Create the KEY token and insert it into the queue. - token := yaml_token_t{ - typ: yaml_KEY_TOKEN, - start_mark: simple_key.mark, - end_mark: simple_key.mark, - } - yaml_insert_token(parser, simple_key.token_number-parser.tokens_parsed, &token) - - // In the block context, we may need to add the BLOCK-MAPPING-START token. - if !yaml_parser_roll_indent(parser, simple_key.mark.column, - simple_key.token_number, - yaml_BLOCK_MAPPING_START_TOKEN, simple_key.mark) { - return false - } - - // Remove the simple key. - simple_key.possible = false - delete(parser.simple_keys_by_tok, simple_key.token_number) - - // A simple key cannot follow another simple key. - parser.simple_key_allowed = false - - } else { - // The ':' indicator follows a complex key. - - // In the block context, extra checks are required. - if parser.flow_level == 0 { - - // Check if we are allowed to start a complex value. - if !parser.simple_key_allowed { - return yaml_parser_set_scanner_error(parser, "", parser.mark, - "mapping values are not allowed in this context") - } - - // Add the BLOCK-MAPPING-START token if needed. - if !yaml_parser_roll_indent(parser, parser.mark.column, -1, yaml_BLOCK_MAPPING_START_TOKEN, parser.mark) { - return false - } - } - - // Simple keys after ':' are allowed in the block context. - parser.simple_key_allowed = parser.flow_level == 0 - } - - // Consume the token. - start_mark := parser.mark - skip(parser) - end_mark := parser.mark - - // Create the VALUE token and append it to the queue. - token := yaml_token_t{ - typ: yaml_VALUE_TOKEN, - start_mark: start_mark, - end_mark: end_mark, - } - yaml_insert_token(parser, -1, &token) - return true -} - -// Produce the ALIAS or ANCHOR token. -func yaml_parser_fetch_anchor(parser *yaml_parser_t, typ yaml_token_type_t) bool { - // An anchor or an alias could be a simple key. - if !yaml_parser_save_simple_key(parser) { - return false - } - - // A simple key cannot follow an anchor or an alias. - parser.simple_key_allowed = false - - // Create the ALIAS or ANCHOR token and append it to the queue. - var token yaml_token_t - if !yaml_parser_scan_anchor(parser, &token, typ) { - return false - } - yaml_insert_token(parser, -1, &token) - return true -} - -// Produce the TAG token. -func yaml_parser_fetch_tag(parser *yaml_parser_t) bool { - // A tag could be a simple key. - if !yaml_parser_save_simple_key(parser) { - return false - } - - // A simple key cannot follow a tag. - parser.simple_key_allowed = false - - // Create the TAG token and append it to the queue. - var token yaml_token_t - if !yaml_parser_scan_tag(parser, &token) { - return false - } - yaml_insert_token(parser, -1, &token) - return true -} - -// Produce the SCALAR(...,literal) or SCALAR(...,folded) tokens. -func yaml_parser_fetch_block_scalar(parser *yaml_parser_t, literal bool) bool { - // Remove any potential simple keys. - if !yaml_parser_remove_simple_key(parser) { - return false - } - - // A simple key may follow a block scalar. - parser.simple_key_allowed = true - - // Create the SCALAR token and append it to the queue. - var token yaml_token_t - if !yaml_parser_scan_block_scalar(parser, &token, literal) { - return false - } - yaml_insert_token(parser, -1, &token) - return true -} - -// Produce the SCALAR(...,single-quoted) or SCALAR(...,double-quoted) tokens. -func yaml_parser_fetch_flow_scalar(parser *yaml_parser_t, single bool) bool { - // A plain scalar could be a simple key. - if !yaml_parser_save_simple_key(parser) { - return false - } - - // A simple key cannot follow a flow scalar. - parser.simple_key_allowed = false - - // Create the SCALAR token and append it to the queue. - var token yaml_token_t - if !yaml_parser_scan_flow_scalar(parser, &token, single) { - return false - } - yaml_insert_token(parser, -1, &token) - return true -} - -// Produce the SCALAR(...,plain) token. -func yaml_parser_fetch_plain_scalar(parser *yaml_parser_t) bool { - // A plain scalar could be a simple key. - if !yaml_parser_save_simple_key(parser) { - return false - } - - // A simple key cannot follow a flow scalar. - parser.simple_key_allowed = false - - // Create the SCALAR token and append it to the queue. - var token yaml_token_t - if !yaml_parser_scan_plain_scalar(parser, &token) { - return false - } - yaml_insert_token(parser, -1, &token) - return true -} - -// Eat whitespaces and comments until the next token is found. -func yaml_parser_scan_to_next_token(parser *yaml_parser_t) bool { - - // Until the next token is not found. - for { - // Allow the BOM mark to start a line. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - if parser.mark.column == 0 && is_bom(parser.buffer, parser.buffer_pos) { - skip(parser) - } - - // Eat whitespaces. - // Tabs are allowed: - // - in the flow context - // - in the block context, but not at the beginning of the line or - // after '-', '?', or ':' (complex value). - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - - for parser.buffer[parser.buffer_pos] == ' ' || ((parser.flow_level > 0 || !parser.simple_key_allowed) && parser.buffer[parser.buffer_pos] == '\t') { - skip(parser) - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - - // Eat a comment until a line break. - if parser.buffer[parser.buffer_pos] == '#' { - for !is_breakz(parser.buffer, parser.buffer_pos) { - skip(parser) - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - } - - // If it is a line break, eat it. - if is_break(parser.buffer, parser.buffer_pos) { - if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { - return false - } - skip_line(parser) - - // In the block context, a new line may start a simple key. - if parser.flow_level == 0 { - parser.simple_key_allowed = true - } - } else { - break // We have found a token. - } - } - - return true -} - -// Scan a YAML-DIRECTIVE or TAG-DIRECTIVE token. -// -// Scope: -// %YAML 1.1 # a comment \n -// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -// %TAG !yaml! tag:yaml.org,2002: \n -// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -// -func yaml_parser_scan_directive(parser *yaml_parser_t, token *yaml_token_t) bool { - // Eat '%'. - start_mark := parser.mark - skip(parser) - - // Scan the directive name. - var name []byte - if !yaml_parser_scan_directive_name(parser, start_mark, &name) { - return false - } - - // Is it a YAML directive? - if bytes.Equal(name, []byte("YAML")) { - // Scan the VERSION directive value. - var major, minor int8 - if !yaml_parser_scan_version_directive_value(parser, start_mark, &major, &minor) { - return false - } - end_mark := parser.mark - - // Create a VERSION-DIRECTIVE token. - *token = yaml_token_t{ - typ: yaml_VERSION_DIRECTIVE_TOKEN, - start_mark: start_mark, - end_mark: end_mark, - major: major, - minor: minor, - } - - // Is it a TAG directive? - } else if bytes.Equal(name, []byte("TAG")) { - // Scan the TAG directive value. - var handle, prefix []byte - if !yaml_parser_scan_tag_directive_value(parser, start_mark, &handle, &prefix) { - return false - } - end_mark := parser.mark - - // Create a TAG-DIRECTIVE token. - *token = yaml_token_t{ - typ: yaml_TAG_DIRECTIVE_TOKEN, - start_mark: start_mark, - end_mark: end_mark, - value: handle, - prefix: prefix, - } - - // Unknown directive. - } else { - yaml_parser_set_scanner_error(parser, "while scanning a directive", - start_mark, "found unknown directive name") - return false - } - - // Eat the rest of the line including any comments. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - - for is_blank(parser.buffer, parser.buffer_pos) { - skip(parser) - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - - if parser.buffer[parser.buffer_pos] == '#' { - for !is_breakz(parser.buffer, parser.buffer_pos) { - skip(parser) - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - } - - // Check if we are at the end of the line. - if !is_breakz(parser.buffer, parser.buffer_pos) { - yaml_parser_set_scanner_error(parser, "while scanning a directive", - start_mark, "did not find expected comment or line break") - return false - } - - // Eat a line break. - if is_break(parser.buffer, parser.buffer_pos) { - if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { - return false - } - skip_line(parser) - } - - return true -} - -// Scan the directive name. -// -// Scope: -// %YAML 1.1 # a comment \n -// ^^^^ -// %TAG !yaml! tag:yaml.org,2002: \n -// ^^^ -// -func yaml_parser_scan_directive_name(parser *yaml_parser_t, start_mark yaml_mark_t, name *[]byte) bool { - // Consume the directive name. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - - var s []byte - for is_alpha(parser.buffer, parser.buffer_pos) { - s = read(parser, s) - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - - // Check if the name is empty. - if len(s) == 0 { - yaml_parser_set_scanner_error(parser, "while scanning a directive", - start_mark, "could not find expected directive name") - return false - } - - // Check for an blank character after the name. - if !is_blankz(parser.buffer, parser.buffer_pos) { - yaml_parser_set_scanner_error(parser, "while scanning a directive", - start_mark, "found unexpected non-alphabetical character") - return false - } - *name = s - return true -} - -// Scan the value of VERSION-DIRECTIVE. -// -// Scope: -// %YAML 1.1 # a comment \n -// ^^^^^^ -func yaml_parser_scan_version_directive_value(parser *yaml_parser_t, start_mark yaml_mark_t, major, minor *int8) bool { - // Eat whitespaces. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - for is_blank(parser.buffer, parser.buffer_pos) { - skip(parser) - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - - // Consume the major version number. - if !yaml_parser_scan_version_directive_number(parser, start_mark, major) { - return false - } - - // Eat '.'. - if parser.buffer[parser.buffer_pos] != '.' { - return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive", - start_mark, "did not find expected digit or '.' character") - } - - skip(parser) - - // Consume the minor version number. - if !yaml_parser_scan_version_directive_number(parser, start_mark, minor) { - return false - } - return true -} - -const max_number_length = 2 - -// Scan the version number of VERSION-DIRECTIVE. -// -// Scope: -// %YAML 1.1 # a comment \n -// ^ -// %YAML 1.1 # a comment \n -// ^ -func yaml_parser_scan_version_directive_number(parser *yaml_parser_t, start_mark yaml_mark_t, number *int8) bool { - - // Repeat while the next character is digit. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - var value, length int8 - for is_digit(parser.buffer, parser.buffer_pos) { - // Check if the number is too long. - length++ - if length > max_number_length { - return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive", - start_mark, "found extremely long version number") - } - value = value*10 + int8(as_digit(parser.buffer, parser.buffer_pos)) - skip(parser) - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - - // Check if the number was present. - if length == 0 { - return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive", - start_mark, "did not find expected version number") - } - *number = value - return true -} - -// Scan the value of a TAG-DIRECTIVE token. -// -// Scope: -// %TAG !yaml! tag:yaml.org,2002: \n -// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -// -func yaml_parser_scan_tag_directive_value(parser *yaml_parser_t, start_mark yaml_mark_t, handle, prefix *[]byte) bool { - var handle_value, prefix_value []byte - - // Eat whitespaces. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - - for is_blank(parser.buffer, parser.buffer_pos) { - skip(parser) - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - - // Scan a handle. - if !yaml_parser_scan_tag_handle(parser, true, start_mark, &handle_value) { - return false - } - - // Expect a whitespace. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - if !is_blank(parser.buffer, parser.buffer_pos) { - yaml_parser_set_scanner_error(parser, "while scanning a %TAG directive", - start_mark, "did not find expected whitespace") - return false - } - - // Eat whitespaces. - for is_blank(parser.buffer, parser.buffer_pos) { - skip(parser) - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - - // Scan a prefix. - if !yaml_parser_scan_tag_uri(parser, true, nil, start_mark, &prefix_value) { - return false - } - - // Expect a whitespace or line break. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - if !is_blankz(parser.buffer, parser.buffer_pos) { - yaml_parser_set_scanner_error(parser, "while scanning a %TAG directive", - start_mark, "did not find expected whitespace or line break") - return false - } - - *handle = handle_value - *prefix = prefix_value - return true -} - -func yaml_parser_scan_anchor(parser *yaml_parser_t, token *yaml_token_t, typ yaml_token_type_t) bool { - var s []byte - - // Eat the indicator character. - start_mark := parser.mark - skip(parser) - - // Consume the value. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - - for is_alpha(parser.buffer, parser.buffer_pos) { - s = read(parser, s) - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - - end_mark := parser.mark - - /* - * Check if length of the anchor is greater than 0 and it is followed by - * a whitespace character or one of the indicators: - * - * '?', ':', ',', ']', '}', '%', '@', '`'. - */ - - if len(s) == 0 || - !(is_blankz(parser.buffer, parser.buffer_pos) || parser.buffer[parser.buffer_pos] == '?' || - parser.buffer[parser.buffer_pos] == ':' || parser.buffer[parser.buffer_pos] == ',' || - parser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '}' || - parser.buffer[parser.buffer_pos] == '%' || parser.buffer[parser.buffer_pos] == '@' || - parser.buffer[parser.buffer_pos] == '`') { - context := "while scanning an alias" - if typ == yaml_ANCHOR_TOKEN { - context = "while scanning an anchor" - } - yaml_parser_set_scanner_error(parser, context, start_mark, - "did not find expected alphabetic or numeric character") - return false - } - - // Create a token. - *token = yaml_token_t{ - typ: typ, - start_mark: start_mark, - end_mark: end_mark, - value: s, - } - - return true -} - -/* - * Scan a TAG token. - */ - -func yaml_parser_scan_tag(parser *yaml_parser_t, token *yaml_token_t) bool { - var handle, suffix []byte - - start_mark := parser.mark - - // Check if the tag is in the canonical form. - if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { - return false - } - - if parser.buffer[parser.buffer_pos+1] == '<' { - // Keep the handle as '' - - // Eat '!<' - skip(parser) - skip(parser) - - // Consume the tag value. - if !yaml_parser_scan_tag_uri(parser, false, nil, start_mark, &suffix) { - return false - } - - // Check for '>' and eat it. - if parser.buffer[parser.buffer_pos] != '>' { - yaml_parser_set_scanner_error(parser, "while scanning a tag", - start_mark, "did not find the expected '>'") - return false - } - - skip(parser) - } else { - // The tag has either the '!suffix' or the '!handle!suffix' form. - - // First, try to scan a handle. - if !yaml_parser_scan_tag_handle(parser, false, start_mark, &handle) { - return false - } - - // Check if it is, indeed, handle. - if handle[0] == '!' && len(handle) > 1 && handle[len(handle)-1] == '!' { - // Scan the suffix now. - if !yaml_parser_scan_tag_uri(parser, false, nil, start_mark, &suffix) { - return false - } - } else { - // It wasn't a handle after all. Scan the rest of the tag. - if !yaml_parser_scan_tag_uri(parser, false, handle, start_mark, &suffix) { - return false - } - - // Set the handle to '!'. - handle = []byte{'!'} - - // A special case: the '!' tag. Set the handle to '' and the - // suffix to '!'. - if len(suffix) == 0 { - handle, suffix = suffix, handle - } - } - } - - // Check the character which ends the tag. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - if !is_blankz(parser.buffer, parser.buffer_pos) { - yaml_parser_set_scanner_error(parser, "while scanning a tag", - start_mark, "did not find expected whitespace or line break") - return false - } - - end_mark := parser.mark - - // Create a token. - *token = yaml_token_t{ - typ: yaml_TAG_TOKEN, - start_mark: start_mark, - end_mark: end_mark, - value: handle, - suffix: suffix, - } - return true -} - -// Scan a tag handle. -func yaml_parser_scan_tag_handle(parser *yaml_parser_t, directive bool, start_mark yaml_mark_t, handle *[]byte) bool { - // Check the initial '!' character. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - if parser.buffer[parser.buffer_pos] != '!' { - yaml_parser_set_scanner_tag_error(parser, directive, - start_mark, "did not find expected '!'") - return false - } - - var s []byte - - // Copy the '!' character. - s = read(parser, s) - - // Copy all subsequent alphabetical and numerical characters. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - for is_alpha(parser.buffer, parser.buffer_pos) { - s = read(parser, s) - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - - // Check if the trailing character is '!' and copy it. - if parser.buffer[parser.buffer_pos] == '!' { - s = read(parser, s) - } else { - // It's either the '!' tag or not really a tag handle. If it's a %TAG - // directive, it's an error. If it's a tag token, it must be a part of URI. - if directive && string(s) != "!" { - yaml_parser_set_scanner_tag_error(parser, directive, - start_mark, "did not find expected '!'") - return false - } - } - - *handle = s - return true -} - -// Scan a tag. -func yaml_parser_scan_tag_uri(parser *yaml_parser_t, directive bool, head []byte, start_mark yaml_mark_t, uri *[]byte) bool { - //size_t length = head ? strlen((char *)head) : 0 - var s []byte - hasTag := len(head) > 0 - - // Copy the head if needed. - // - // Note that we don't copy the leading '!' character. - if len(head) > 1 { - s = append(s, head[1:]...) - } - - // Scan the tag. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - - // The set of characters that may appear in URI is as follows: - // - // '0'-'9', 'A'-'Z', 'a'-'z', '_', '-', ';', '/', '?', ':', '@', '&', - // '=', '+', '$', ',', '.', '!', '~', '*', '\'', '(', ')', '[', ']', - // '%'. - // [Go] Convert this into more reasonable logic. - for is_alpha(parser.buffer, parser.buffer_pos) || parser.buffer[parser.buffer_pos] == ';' || - parser.buffer[parser.buffer_pos] == '/' || parser.buffer[parser.buffer_pos] == '?' || - parser.buffer[parser.buffer_pos] == ':' || parser.buffer[parser.buffer_pos] == '@' || - parser.buffer[parser.buffer_pos] == '&' || parser.buffer[parser.buffer_pos] == '=' || - parser.buffer[parser.buffer_pos] == '+' || parser.buffer[parser.buffer_pos] == '$' || - parser.buffer[parser.buffer_pos] == ',' || parser.buffer[parser.buffer_pos] == '.' || - parser.buffer[parser.buffer_pos] == '!' || parser.buffer[parser.buffer_pos] == '~' || - parser.buffer[parser.buffer_pos] == '*' || parser.buffer[parser.buffer_pos] == '\'' || - parser.buffer[parser.buffer_pos] == '(' || parser.buffer[parser.buffer_pos] == ')' || - parser.buffer[parser.buffer_pos] == '[' || parser.buffer[parser.buffer_pos] == ']' || - parser.buffer[parser.buffer_pos] == '%' { - // Check if it is a URI-escape sequence. - if parser.buffer[parser.buffer_pos] == '%' { - if !yaml_parser_scan_uri_escapes(parser, directive, start_mark, &s) { - return false - } - } else { - s = read(parser, s) - } - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - hasTag = true - } - - if !hasTag { - yaml_parser_set_scanner_tag_error(parser, directive, - start_mark, "did not find expected tag URI") - return false - } - *uri = s - return true -} - -// Decode an URI-escape sequence corresponding to a single UTF-8 character. -func yaml_parser_scan_uri_escapes(parser *yaml_parser_t, directive bool, start_mark yaml_mark_t, s *[]byte) bool { - - // Decode the required number of characters. - w := 1024 - for w > 0 { - // Check for a URI-escaped octet. - if parser.unread < 3 && !yaml_parser_update_buffer(parser, 3) { - return false - } - - if !(parser.buffer[parser.buffer_pos] == '%' && - is_hex(parser.buffer, parser.buffer_pos+1) && - is_hex(parser.buffer, parser.buffer_pos+2)) { - return yaml_parser_set_scanner_tag_error(parser, directive, - start_mark, "did not find URI escaped octet") - } - - // Get the octet. - octet := byte((as_hex(parser.buffer, parser.buffer_pos+1) << 4) + as_hex(parser.buffer, parser.buffer_pos+2)) - - // If it is the leading octet, determine the length of the UTF-8 sequence. - if w == 1024 { - w = width(octet) - if w == 0 { - return yaml_parser_set_scanner_tag_error(parser, directive, - start_mark, "found an incorrect leading UTF-8 octet") - } - } else { - // Check if the trailing octet is correct. - if octet&0xC0 != 0x80 { - return yaml_parser_set_scanner_tag_error(parser, directive, - start_mark, "found an incorrect trailing UTF-8 octet") - } - } - - // Copy the octet and move the pointers. - *s = append(*s, octet) - skip(parser) - skip(parser) - skip(parser) - w-- - } - return true -} - -// Scan a block scalar. -func yaml_parser_scan_block_scalar(parser *yaml_parser_t, token *yaml_token_t, literal bool) bool { - // Eat the indicator '|' or '>'. - start_mark := parser.mark - skip(parser) - - // Scan the additional block scalar indicators. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - - // Check for a chomping indicator. - var chomping, increment int - if parser.buffer[parser.buffer_pos] == '+' || parser.buffer[parser.buffer_pos] == '-' { - // Set the chomping method and eat the indicator. - if parser.buffer[parser.buffer_pos] == '+' { - chomping = +1 - } else { - chomping = -1 - } - skip(parser) - - // Check for an indentation indicator. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - if is_digit(parser.buffer, parser.buffer_pos) { - // Check that the indentation is greater than 0. - if parser.buffer[parser.buffer_pos] == '0' { - yaml_parser_set_scanner_error(parser, "while scanning a block scalar", - start_mark, "found an indentation indicator equal to 0") - return false - } - - // Get the indentation level and eat the indicator. - increment = as_digit(parser.buffer, parser.buffer_pos) - skip(parser) - } - - } else if is_digit(parser.buffer, parser.buffer_pos) { - // Do the same as above, but in the opposite order. - - if parser.buffer[parser.buffer_pos] == '0' { - yaml_parser_set_scanner_error(parser, "while scanning a block scalar", - start_mark, "found an indentation indicator equal to 0") - return false - } - increment = as_digit(parser.buffer, parser.buffer_pos) - skip(parser) - - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - if parser.buffer[parser.buffer_pos] == '+' || parser.buffer[parser.buffer_pos] == '-' { - if parser.buffer[parser.buffer_pos] == '+' { - chomping = +1 - } else { - chomping = -1 - } - skip(parser) - } - } - - // Eat whitespaces and comments to the end of the line. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - for is_blank(parser.buffer, parser.buffer_pos) { - skip(parser) - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - if parser.buffer[parser.buffer_pos] == '#' { - for !is_breakz(parser.buffer, parser.buffer_pos) { - skip(parser) - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - } - - // Check if we are at the end of the line. - if !is_breakz(parser.buffer, parser.buffer_pos) { - yaml_parser_set_scanner_error(parser, "while scanning a block scalar", - start_mark, "did not find expected comment or line break") - return false - } - - // Eat a line break. - if is_break(parser.buffer, parser.buffer_pos) { - if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { - return false - } - skip_line(parser) - } - - end_mark := parser.mark - - // Set the indentation level if it was specified. - var indent int - if increment > 0 { - if parser.indent >= 0 { - indent = parser.indent + increment - } else { - indent = increment - } - } - - // Scan the leading line breaks and determine the indentation level if needed. - var s, leading_break, trailing_breaks []byte - if !yaml_parser_scan_block_scalar_breaks(parser, &indent, &trailing_breaks, start_mark, &end_mark) { - return false - } - - // Scan the block scalar content. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - var leading_blank, trailing_blank bool - for parser.mark.column == indent && !is_z(parser.buffer, parser.buffer_pos) { - // We are at the beginning of a non-empty line. - - // Is it a trailing whitespace? - trailing_blank = is_blank(parser.buffer, parser.buffer_pos) - - // Check if we need to fold the leading line break. - if !literal && !leading_blank && !trailing_blank && len(leading_break) > 0 && leading_break[0] == '\n' { - // Do we need to join the lines by space? - if len(trailing_breaks) == 0 { - s = append(s, ' ') - } - } else { - s = append(s, leading_break...) - } - leading_break = leading_break[:0] - - // Append the remaining line breaks. - s = append(s, trailing_breaks...) - trailing_breaks = trailing_breaks[:0] - - // Is it a leading whitespace? - leading_blank = is_blank(parser.buffer, parser.buffer_pos) - - // Consume the current line. - for !is_breakz(parser.buffer, parser.buffer_pos) { - s = read(parser, s) - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - - // Consume the line break. - if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { - return false - } - - leading_break = read_line(parser, leading_break) - - // Eat the following indentation spaces and line breaks. - if !yaml_parser_scan_block_scalar_breaks(parser, &indent, &trailing_breaks, start_mark, &end_mark) { - return false - } - } - - // Chomp the tail. - if chomping != -1 { - s = append(s, leading_break...) - } - if chomping == 1 { - s = append(s, trailing_breaks...) - } - - // Create a token. - *token = yaml_token_t{ - typ: yaml_SCALAR_TOKEN, - start_mark: start_mark, - end_mark: end_mark, - value: s, - style: yaml_LITERAL_SCALAR_STYLE, - } - if !literal { - token.style = yaml_FOLDED_SCALAR_STYLE - } - return true -} - -// Scan indentation spaces and line breaks for a block scalar. Determine the -// indentation level if needed. -func yaml_parser_scan_block_scalar_breaks(parser *yaml_parser_t, indent *int, breaks *[]byte, start_mark yaml_mark_t, end_mark *yaml_mark_t) bool { - *end_mark = parser.mark - - // Eat the indentation spaces and line breaks. - max_indent := 0 - for { - // Eat the indentation spaces. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - for (*indent == 0 || parser.mark.column < *indent) && is_space(parser.buffer, parser.buffer_pos) { - skip(parser) - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - if parser.mark.column > max_indent { - max_indent = parser.mark.column - } - - // Check for a tab character messing the indentation. - if (*indent == 0 || parser.mark.column < *indent) && is_tab(parser.buffer, parser.buffer_pos) { - return yaml_parser_set_scanner_error(parser, "while scanning a block scalar", - start_mark, "found a tab character where an indentation space is expected") - } - - // Have we found a non-empty line? - if !is_break(parser.buffer, parser.buffer_pos) { - break - } - - // Consume the line break. - if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { - return false - } - // [Go] Should really be returning breaks instead. - *breaks = read_line(parser, *breaks) - *end_mark = parser.mark - } - - // Determine the indentation level if needed. - if *indent == 0 { - *indent = max_indent - if *indent < parser.indent+1 { - *indent = parser.indent + 1 - } - if *indent < 1 { - *indent = 1 - } - } - return true -} - -// Scan a quoted scalar. -func yaml_parser_scan_flow_scalar(parser *yaml_parser_t, token *yaml_token_t, single bool) bool { - // Eat the left quote. - start_mark := parser.mark - skip(parser) - - // Consume the content of the quoted scalar. - var s, leading_break, trailing_breaks, whitespaces []byte - for { - // Check that there are no document indicators at the beginning of the line. - if parser.unread < 4 && !yaml_parser_update_buffer(parser, 4) { - return false - } - - if parser.mark.column == 0 && - ((parser.buffer[parser.buffer_pos+0] == '-' && - parser.buffer[parser.buffer_pos+1] == '-' && - parser.buffer[parser.buffer_pos+2] == '-') || - (parser.buffer[parser.buffer_pos+0] == '.' && - parser.buffer[parser.buffer_pos+1] == '.' && - parser.buffer[parser.buffer_pos+2] == '.')) && - is_blankz(parser.buffer, parser.buffer_pos+3) { - yaml_parser_set_scanner_error(parser, "while scanning a quoted scalar", - start_mark, "found unexpected document indicator") - return false - } - - // Check for EOF. - if is_z(parser.buffer, parser.buffer_pos) { - yaml_parser_set_scanner_error(parser, "while scanning a quoted scalar", - start_mark, "found unexpected end of stream") - return false - } - - // Consume non-blank characters. - leading_blanks := false - for !is_blankz(parser.buffer, parser.buffer_pos) { - if single && parser.buffer[parser.buffer_pos] == '\'' && parser.buffer[parser.buffer_pos+1] == '\'' { - // Is is an escaped single quote. - s = append(s, '\'') - skip(parser) - skip(parser) - - } else if single && parser.buffer[parser.buffer_pos] == '\'' { - // It is a right single quote. - break - } else if !single && parser.buffer[parser.buffer_pos] == '"' { - // It is a right double quote. - break - - } else if !single && parser.buffer[parser.buffer_pos] == '\\' && is_break(parser.buffer, parser.buffer_pos+1) { - // It is an escaped line break. - if parser.unread < 3 && !yaml_parser_update_buffer(parser, 3) { - return false - } - skip(parser) - skip_line(parser) - leading_blanks = true - break - - } else if !single && parser.buffer[parser.buffer_pos] == '\\' { - // It is an escape sequence. - code_length := 0 - - // Check the escape character. - switch parser.buffer[parser.buffer_pos+1] { - case '0': - s = append(s, 0) - case 'a': - s = append(s, '\x07') - case 'b': - s = append(s, '\x08') - case 't', '\t': - s = append(s, '\x09') - case 'n': - s = append(s, '\x0A') - case 'v': - s = append(s, '\x0B') - case 'f': - s = append(s, '\x0C') - case 'r': - s = append(s, '\x0D') - case 'e': - s = append(s, '\x1B') - case ' ': - s = append(s, '\x20') - case '"': - s = append(s, '"') - case '\'': - s = append(s, '\'') - case '\\': - s = append(s, '\\') - case 'N': // NEL (#x85) - s = append(s, '\xC2') - s = append(s, '\x85') - case '_': // #xA0 - s = append(s, '\xC2') - s = append(s, '\xA0') - case 'L': // LS (#x2028) - s = append(s, '\xE2') - s = append(s, '\x80') - s = append(s, '\xA8') - case 'P': // PS (#x2029) - s = append(s, '\xE2') - s = append(s, '\x80') - s = append(s, '\xA9') - case 'x': - code_length = 2 - case 'u': - code_length = 4 - case 'U': - code_length = 8 - default: - yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar", - start_mark, "found unknown escape character") - return false - } - - skip(parser) - skip(parser) - - // Consume an arbitrary escape code. - if code_length > 0 { - var value int - - // Scan the character value. - if parser.unread < code_length && !yaml_parser_update_buffer(parser, code_length) { - return false - } - for k := 0; k < code_length; k++ { - if !is_hex(parser.buffer, parser.buffer_pos+k) { - yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar", - start_mark, "did not find expected hexdecimal number") - return false - } - value = (value << 4) + as_hex(parser.buffer, parser.buffer_pos+k) - } - - // Check the value and write the character. - if (value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF { - yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar", - start_mark, "found invalid Unicode character escape code") - return false - } - if value <= 0x7F { - s = append(s, byte(value)) - } else if value <= 0x7FF { - s = append(s, byte(0xC0+(value>>6))) - s = append(s, byte(0x80+(value&0x3F))) - } else if value <= 0xFFFF { - s = append(s, byte(0xE0+(value>>12))) - s = append(s, byte(0x80+((value>>6)&0x3F))) - s = append(s, byte(0x80+(value&0x3F))) - } else { - s = append(s, byte(0xF0+(value>>18))) - s = append(s, byte(0x80+((value>>12)&0x3F))) - s = append(s, byte(0x80+((value>>6)&0x3F))) - s = append(s, byte(0x80+(value&0x3F))) - } - - // Advance the pointer. - for k := 0; k < code_length; k++ { - skip(parser) - } - } - } else { - // It is a non-escaped non-blank character. - s = read(parser, s) - } - if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { - return false - } - } - - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - - // Check if we are at the end of the scalar. - if single { - if parser.buffer[parser.buffer_pos] == '\'' { - break - } - } else { - if parser.buffer[parser.buffer_pos] == '"' { - break - } - } - - // Consume blank characters. - for is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos) { - if is_blank(parser.buffer, parser.buffer_pos) { - // Consume a space or a tab character. - if !leading_blanks { - whitespaces = read(parser, whitespaces) - } else { - skip(parser) - } - } else { - if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { - return false - } - - // Check if it is a first line break. - if !leading_blanks { - whitespaces = whitespaces[:0] - leading_break = read_line(parser, leading_break) - leading_blanks = true - } else { - trailing_breaks = read_line(parser, trailing_breaks) - } - } - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - - // Join the whitespaces or fold line breaks. - if leading_blanks { - // Do we need to fold line breaks? - if len(leading_break) > 0 && leading_break[0] == '\n' { - if len(trailing_breaks) == 0 { - s = append(s, ' ') - } else { - s = append(s, trailing_breaks...) - } - } else { - s = append(s, leading_break...) - s = append(s, trailing_breaks...) - } - trailing_breaks = trailing_breaks[:0] - leading_break = leading_break[:0] - } else { - s = append(s, whitespaces...) - whitespaces = whitespaces[:0] - } - } - - // Eat the right quote. - skip(parser) - end_mark := parser.mark - - // Create a token. - *token = yaml_token_t{ - typ: yaml_SCALAR_TOKEN, - start_mark: start_mark, - end_mark: end_mark, - value: s, - style: yaml_SINGLE_QUOTED_SCALAR_STYLE, - } - if !single { - token.style = yaml_DOUBLE_QUOTED_SCALAR_STYLE - } - return true -} - -// Scan a plain scalar. -func yaml_parser_scan_plain_scalar(parser *yaml_parser_t, token *yaml_token_t) bool { - - var s, leading_break, trailing_breaks, whitespaces []byte - var leading_blanks bool - var indent = parser.indent + 1 - - start_mark := parser.mark - end_mark := parser.mark - - // Consume the content of the plain scalar. - for { - // Check for a document indicator. - if parser.unread < 4 && !yaml_parser_update_buffer(parser, 4) { - return false - } - if parser.mark.column == 0 && - ((parser.buffer[parser.buffer_pos+0] == '-' && - parser.buffer[parser.buffer_pos+1] == '-' && - parser.buffer[parser.buffer_pos+2] == '-') || - (parser.buffer[parser.buffer_pos+0] == '.' && - parser.buffer[parser.buffer_pos+1] == '.' && - parser.buffer[parser.buffer_pos+2] == '.')) && - is_blankz(parser.buffer, parser.buffer_pos+3) { - break - } - - // Check for a comment. - if parser.buffer[parser.buffer_pos] == '#' { - break - } - - // Consume non-blank characters. - for !is_blankz(parser.buffer, parser.buffer_pos) { - - // Check for indicators that may end a plain scalar. - if (parser.buffer[parser.buffer_pos] == ':' && is_blankz(parser.buffer, parser.buffer_pos+1)) || - (parser.flow_level > 0 && - (parser.buffer[parser.buffer_pos] == ',' || - parser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == '[' || - parser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '{' || - parser.buffer[parser.buffer_pos] == '}')) { - break - } - - // Check if we need to join whitespaces and breaks. - if leading_blanks || len(whitespaces) > 0 { - if leading_blanks { - // Do we need to fold line breaks? - if leading_break[0] == '\n' { - if len(trailing_breaks) == 0 { - s = append(s, ' ') - } else { - s = append(s, trailing_breaks...) - } - } else { - s = append(s, leading_break...) - s = append(s, trailing_breaks...) - } - trailing_breaks = trailing_breaks[:0] - leading_break = leading_break[:0] - leading_blanks = false - } else { - s = append(s, whitespaces...) - whitespaces = whitespaces[:0] - } - } - - // Copy the character. - s = read(parser, s) - - end_mark = parser.mark - if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { - return false - } - } - - // Is it the end? - if !(is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos)) { - break - } - - // Consume blank characters. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - - for is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos) { - if is_blank(parser.buffer, parser.buffer_pos) { - - // Check for tab characters that abuse indentation. - if leading_blanks && parser.mark.column < indent && is_tab(parser.buffer, parser.buffer_pos) { - yaml_parser_set_scanner_error(parser, "while scanning a plain scalar", - start_mark, "found a tab character that violates indentation") - return false - } - - // Consume a space or a tab character. - if !leading_blanks { - whitespaces = read(parser, whitespaces) - } else { - skip(parser) - } - } else { - if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { - return false - } - - // Check if it is a first line break. - if !leading_blanks { - whitespaces = whitespaces[:0] - leading_break = read_line(parser, leading_break) - leading_blanks = true - } else { - trailing_breaks = read_line(parser, trailing_breaks) - } - } - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - - // Check indentation level. - if parser.flow_level == 0 && parser.mark.column < indent { - break - } - } - - // Create a token. - *token = yaml_token_t{ - typ: yaml_SCALAR_TOKEN, - start_mark: start_mark, - end_mark: end_mark, - value: s, - style: yaml_PLAIN_SCALAR_STYLE, - } - - // Note that we change the 'simple_key_allowed' flag. - if leading_blanks { - parser.simple_key_allowed = true - } - return true -} diff --git a/vendor/gopkg.in/yaml.v2/sorter.go b/vendor/gopkg.in/yaml.v2/sorter.go deleted file mode 100644 index 4c45e660a8..0000000000 --- a/vendor/gopkg.in/yaml.v2/sorter.go +++ /dev/null @@ -1,113 +0,0 @@ -package yaml - -import ( - "reflect" - "unicode" -) - -type keyList []reflect.Value - -func (l keyList) Len() int { return len(l) } -func (l keyList) Swap(i, j int) { l[i], l[j] = l[j], l[i] } -func (l keyList) Less(i, j int) bool { - a := l[i] - b := l[j] - ak := a.Kind() - bk := b.Kind() - for (ak == reflect.Interface || ak == reflect.Ptr) && !a.IsNil() { - a = a.Elem() - ak = a.Kind() - } - for (bk == reflect.Interface || bk == reflect.Ptr) && !b.IsNil() { - b = b.Elem() - bk = b.Kind() - } - af, aok := keyFloat(a) - bf, bok := keyFloat(b) - if aok && bok { - if af != bf { - return af < bf - } - if ak != bk { - return ak < bk - } - return numLess(a, b) - } - if ak != reflect.String || bk != reflect.String { - return ak < bk - } - ar, br := []rune(a.String()), []rune(b.String()) - for i := 0; i < len(ar) && i < len(br); i++ { - if ar[i] == br[i] { - continue - } - al := unicode.IsLetter(ar[i]) - bl := unicode.IsLetter(br[i]) - if al && bl { - return ar[i] < br[i] - } - if al || bl { - return bl - } - var ai, bi int - var an, bn int64 - if ar[i] == '0' || br[i] == '0' { - for j := i-1; j >= 0 && unicode.IsDigit(ar[j]); j-- { - if ar[j] != '0' { - an = 1 - bn = 1 - break - } - } - } - for ai = i; ai < len(ar) && unicode.IsDigit(ar[ai]); ai++ { - an = an*10 + int64(ar[ai]-'0') - } - for bi = i; bi < len(br) && unicode.IsDigit(br[bi]); bi++ { - bn = bn*10 + int64(br[bi]-'0') - } - if an != bn { - return an < bn - } - if ai != bi { - return ai < bi - } - return ar[i] < br[i] - } - return len(ar) < len(br) -} - -// keyFloat returns a float value for v if it is a number/bool -// and whether it is a number/bool or not. -func keyFloat(v reflect.Value) (f float64, ok bool) { - switch v.Kind() { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return float64(v.Int()), true - case reflect.Float32, reflect.Float64: - return v.Float(), true - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - return float64(v.Uint()), true - case reflect.Bool: - if v.Bool() { - return 1, true - } - return 0, true - } - return 0, false -} - -// numLess returns whether a < b. -// a and b must necessarily have the same kind. -func numLess(a, b reflect.Value) bool { - switch a.Kind() { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return a.Int() < b.Int() - case reflect.Float32, reflect.Float64: - return a.Float() < b.Float() - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - return a.Uint() < b.Uint() - case reflect.Bool: - return !a.Bool() && b.Bool() - } - panic("not a number") -} diff --git a/vendor/gopkg.in/yaml.v2/writerc.go b/vendor/gopkg.in/yaml.v2/writerc.go deleted file mode 100644 index a2dde608cb..0000000000 --- a/vendor/gopkg.in/yaml.v2/writerc.go +++ /dev/null @@ -1,26 +0,0 @@ -package yaml - -// Set the writer error and return false. -func yaml_emitter_set_writer_error(emitter *yaml_emitter_t, problem string) bool { - emitter.error = yaml_WRITER_ERROR - emitter.problem = problem - return false -} - -// Flush the output buffer. -func yaml_emitter_flush(emitter *yaml_emitter_t) bool { - if emitter.write_handler == nil { - panic("write handler not set") - } - - // Check if the buffer is empty. - if emitter.buffer_pos == 0 { - return true - } - - if err := emitter.write_handler(emitter, emitter.buffer[:emitter.buffer_pos]); err != nil { - return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error()) - } - emitter.buffer_pos = 0 - return true -} diff --git a/vendor/gopkg.in/yaml.v2/yaml.go b/vendor/gopkg.in/yaml.v2/yaml.go deleted file mode 100644 index 30813884c0..0000000000 --- a/vendor/gopkg.in/yaml.v2/yaml.go +++ /dev/null @@ -1,478 +0,0 @@ -// Package yaml implements YAML support for the Go language. -// -// Source code and other details for the project are available at GitHub: -// -// https://github.com/go-yaml/yaml -// -package yaml - -import ( - "errors" - "fmt" - "io" - "reflect" - "strings" - "sync" -) - -// MapSlice encodes and decodes as a YAML map. -// The order of keys is preserved when encoding and decoding. -type MapSlice []MapItem - -// MapItem is an item in a MapSlice. -type MapItem struct { - Key, Value interface{} -} - -// The Unmarshaler interface may be implemented by types to customize their -// behavior when being unmarshaled from a YAML document. The UnmarshalYAML -// method receives a function that may be called to unmarshal the original -// YAML value into a field or variable. It is safe to call the unmarshal -// function parameter more than once if necessary. -type Unmarshaler interface { - UnmarshalYAML(unmarshal func(interface{}) error) error -} - -// The Marshaler interface may be implemented by types to customize their -// behavior when being marshaled into a YAML document. The returned value -// is marshaled in place of the original value implementing Marshaler. -// -// If an error is returned by MarshalYAML, the marshaling procedure stops -// and returns with the provided error. -type Marshaler interface { - MarshalYAML() (interface{}, error) -} - -// Unmarshal decodes the first document found within the in byte slice -// and assigns decoded values into the out value. -// -// Maps and pointers (to a struct, string, int, etc) are accepted as out -// values. If an internal pointer within a struct is not initialized, -// the yaml package will initialize it if necessary for unmarshalling -// the provided data. The out parameter must not be nil. -// -// The type of the decoded values should be compatible with the respective -// values in out. If one or more values cannot be decoded due to a type -// mismatches, decoding continues partially until the end of the YAML -// content, and a *yaml.TypeError is returned with details for all -// missed values. -// -// Struct fields are only unmarshalled if they are exported (have an -// upper case first letter), and are unmarshalled using the field name -// lowercased as the default key. Custom keys may be defined via the -// "yaml" name in the field tag: the content preceding the first comma -// is used as the key, and the following comma-separated options are -// used to tweak the marshalling process (see Marshal). -// Conflicting names result in a runtime error. -// -// For example: -// -// type T struct { -// F int `yaml:"a,omitempty"` -// B int -// } -// var t T -// yaml.Unmarshal([]byte("a: 1\nb: 2"), &t) -// -// See the documentation of Marshal for the format of tags and a list of -// supported tag options. -// -func Unmarshal(in []byte, out interface{}) (err error) { - return unmarshal(in, out, false) -} - -// UnmarshalStrict is like Unmarshal except that any fields that are found -// in the data that do not have corresponding struct members, or mapping -// keys that are duplicates, will result in -// an error. -func UnmarshalStrict(in []byte, out interface{}) (err error) { - return unmarshal(in, out, true) -} - -// A Decoder reads and decodes YAML values from an input stream. -type Decoder struct { - strict bool - parser *parser -} - -// NewDecoder returns a new decoder that reads from r. -// -// The decoder introduces its own buffering and may read -// data from r beyond the YAML values requested. -func NewDecoder(r io.Reader) *Decoder { - return &Decoder{ - parser: newParserFromReader(r), - } -} - -// SetStrict sets whether strict decoding behaviour is enabled when -// decoding items in the data (see UnmarshalStrict). By default, decoding is not strict. -func (dec *Decoder) SetStrict(strict bool) { - dec.strict = strict -} - -// Decode reads the next YAML-encoded value from its input -// and stores it in the value pointed to by v. -// -// See the documentation for Unmarshal for details about the -// conversion of YAML into a Go value. -func (dec *Decoder) Decode(v interface{}) (err error) { - d := newDecoder(dec.strict) - defer handleErr(&err) - node := dec.parser.parse() - if node == nil { - return io.EOF - } - out := reflect.ValueOf(v) - if out.Kind() == reflect.Ptr && !out.IsNil() { - out = out.Elem() - } - d.unmarshal(node, out) - if len(d.terrors) > 0 { - return &TypeError{d.terrors} - } - return nil -} - -func unmarshal(in []byte, out interface{}, strict bool) (err error) { - defer handleErr(&err) - d := newDecoder(strict) - p := newParser(in) - defer p.destroy() - node := p.parse() - if node != nil { - v := reflect.ValueOf(out) - if v.Kind() == reflect.Ptr && !v.IsNil() { - v = v.Elem() - } - d.unmarshal(node, v) - } - if len(d.terrors) > 0 { - return &TypeError{d.terrors} - } - return nil -} - -// Marshal serializes the value provided into a YAML document. The structure -// of the generated document will reflect the structure of the value itself. -// Maps and pointers (to struct, string, int, etc) are accepted as the in value. -// -// Struct fields are only marshalled if they are exported (have an upper case -// first letter), and are marshalled using the field name lowercased as the -// default key. Custom keys may be defined via the "yaml" name in the field -// tag: the content preceding the first comma is used as the key, and the -// following comma-separated options are used to tweak the marshalling process. -// Conflicting names result in a runtime error. -// -// The field tag format accepted is: -// -// `(...) yaml:"[][,[,]]" (...)` -// -// The following flags are currently supported: -// -// omitempty Only include the field if it's not set to the zero -// value for the type or to empty slices or maps. -// Zero valued structs will be omitted if all their public -// fields are zero, unless they implement an IsZero -// method (see the IsZeroer interface type), in which -// case the field will be excluded if IsZero returns true. -// -// flow Marshal using a flow style (useful for structs, -// sequences and maps). -// -// inline Inline the field, which must be a struct or a map, -// causing all of its fields or keys to be processed as if -// they were part of the outer struct. For maps, keys must -// not conflict with the yaml keys of other struct fields. -// -// In addition, if the key is "-", the field is ignored. -// -// For example: -// -// type T struct { -// F int `yaml:"a,omitempty"` -// B int -// } -// yaml.Marshal(&T{B: 2}) // Returns "b: 2\n" -// yaml.Marshal(&T{F: 1}} // Returns "a: 1\nb: 0\n" -// -func Marshal(in interface{}) (out []byte, err error) { - defer handleErr(&err) - e := newEncoder() - defer e.destroy() - e.marshalDoc("", reflect.ValueOf(in)) - e.finish() - out = e.out - return -} - -// An Encoder writes YAML values to an output stream. -type Encoder struct { - encoder *encoder -} - -// NewEncoder returns a new encoder that writes to w. -// The Encoder should be closed after use to flush all data -// to w. -func NewEncoder(w io.Writer) *Encoder { - return &Encoder{ - encoder: newEncoderWithWriter(w), - } -} - -// Encode writes the YAML encoding of v to the stream. -// If multiple items are encoded to the stream, the -// second and subsequent document will be preceded -// with a "---" document separator, but the first will not. -// -// See the documentation for Marshal for details about the conversion of Go -// values to YAML. -func (e *Encoder) Encode(v interface{}) (err error) { - defer handleErr(&err) - e.encoder.marshalDoc("", reflect.ValueOf(v)) - return nil -} - -// Close closes the encoder by writing any remaining data. -// It does not write a stream terminating string "...". -func (e *Encoder) Close() (err error) { - defer handleErr(&err) - e.encoder.finish() - return nil -} - -func handleErr(err *error) { - if v := recover(); v != nil { - if e, ok := v.(yamlError); ok { - *err = e.err - } else { - panic(v) - } - } -} - -type yamlError struct { - err error -} - -func fail(err error) { - panic(yamlError{err}) -} - -func failf(format string, args ...interface{}) { - panic(yamlError{fmt.Errorf("yaml: "+format, args...)}) -} - -// A TypeError is returned by Unmarshal when one or more fields in -// the YAML document cannot be properly decoded into the requested -// types. When this error is returned, the value is still -// unmarshaled partially. -type TypeError struct { - Errors []string -} - -func (e *TypeError) Error() string { - return fmt.Sprintf("yaml: unmarshal errors:\n %s", strings.Join(e.Errors, "\n ")) -} - -// -------------------------------------------------------------------------- -// Maintain a mapping of keys to structure field indexes - -// The code in this section was copied from mgo/bson. - -// structInfo holds details for the serialization of fields of -// a given struct. -type structInfo struct { - FieldsMap map[string]fieldInfo - FieldsList []fieldInfo - - // InlineMap is the number of the field in the struct that - // contains an ,inline map, or -1 if there's none. - InlineMap int -} - -type fieldInfo struct { - Key string - Num int - OmitEmpty bool - Flow bool - // Id holds the unique field identifier, so we can cheaply - // check for field duplicates without maintaining an extra map. - Id int - - // Inline holds the field index if the field is part of an inlined struct. - Inline []int -} - -var structMap = make(map[reflect.Type]*structInfo) -var fieldMapMutex sync.RWMutex - -func getStructInfo(st reflect.Type) (*structInfo, error) { - fieldMapMutex.RLock() - sinfo, found := structMap[st] - fieldMapMutex.RUnlock() - if found { - return sinfo, nil - } - - n := st.NumField() - fieldsMap := make(map[string]fieldInfo) - fieldsList := make([]fieldInfo, 0, n) - inlineMap := -1 - for i := 0; i != n; i++ { - field := st.Field(i) - if field.PkgPath != "" && !field.Anonymous { - continue // Private field - } - - info := fieldInfo{Num: i} - - tag := field.Tag.Get("yaml") - if tag == "" && strings.Index(string(field.Tag), ":") < 0 { - tag = string(field.Tag) - } - if tag == "-" { - continue - } - - inline := false - fields := strings.Split(tag, ",") - if len(fields) > 1 { - for _, flag := range fields[1:] { - switch flag { - case "omitempty": - info.OmitEmpty = true - case "flow": - info.Flow = true - case "inline": - inline = true - default: - return nil, errors.New(fmt.Sprintf("Unsupported flag %q in tag %q of type %s", flag, tag, st)) - } - } - tag = fields[0] - } - - if inline { - switch field.Type.Kind() { - case reflect.Map: - if inlineMap >= 0 { - return nil, errors.New("Multiple ,inline maps in struct " + st.String()) - } - if field.Type.Key() != reflect.TypeOf("") { - return nil, errors.New("Option ,inline needs a map with string keys in struct " + st.String()) - } - inlineMap = info.Num - case reflect.Struct: - sinfo, err := getStructInfo(field.Type) - if err != nil { - return nil, err - } - for _, finfo := range sinfo.FieldsList { - if _, found := fieldsMap[finfo.Key]; found { - msg := "Duplicated key '" + finfo.Key + "' in struct " + st.String() - return nil, errors.New(msg) - } - if finfo.Inline == nil { - finfo.Inline = []int{i, finfo.Num} - } else { - finfo.Inline = append([]int{i}, finfo.Inline...) - } - finfo.Id = len(fieldsList) - fieldsMap[finfo.Key] = finfo - fieldsList = append(fieldsList, finfo) - } - default: - //return nil, errors.New("Option ,inline needs a struct value or map field") - return nil, errors.New("Option ,inline needs a struct value field") - } - continue - } - - if tag != "" { - info.Key = tag - } else { - info.Key = strings.ToLower(field.Name) - } - - if _, found = fieldsMap[info.Key]; found { - msg := "Duplicated key '" + info.Key + "' in struct " + st.String() - return nil, errors.New(msg) - } - - info.Id = len(fieldsList) - fieldsList = append(fieldsList, info) - fieldsMap[info.Key] = info - } - - sinfo = &structInfo{ - FieldsMap: fieldsMap, - FieldsList: fieldsList, - InlineMap: inlineMap, - } - - fieldMapMutex.Lock() - structMap[st] = sinfo - fieldMapMutex.Unlock() - return sinfo, nil -} - -// IsZeroer is used to check whether an object is zero to -// determine whether it should be omitted when marshaling -// with the omitempty flag. One notable implementation -// is time.Time. -type IsZeroer interface { - IsZero() bool -} - -func isZero(v reflect.Value) bool { - kind := v.Kind() - if z, ok := v.Interface().(IsZeroer); ok { - if (kind == reflect.Ptr || kind == reflect.Interface) && v.IsNil() { - return true - } - return z.IsZero() - } - switch kind { - case reflect.String: - return len(v.String()) == 0 - case reflect.Interface, reflect.Ptr: - return v.IsNil() - case reflect.Slice: - return v.Len() == 0 - case reflect.Map: - return v.Len() == 0 - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return v.Int() == 0 - case reflect.Float32, reflect.Float64: - return v.Float() == 0 - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - return v.Uint() == 0 - case reflect.Bool: - return !v.Bool() - case reflect.Struct: - vt := v.Type() - for i := v.NumField() - 1; i >= 0; i-- { - if vt.Field(i).PkgPath != "" { - continue // Private field - } - if !isZero(v.Field(i)) { - return false - } - } - return true - } - return false -} - -// FutureLineWrap globally disables line wrapping when encoding long strings. -// This is a temporary and thus deprecated method introduced to faciliate -// migration towards v3, which offers more control of line lengths on -// individual encodings, and has a default matching the behavior introduced -// by this function. -// -// The default formatting of v2 was erroneously changed in v2.3.0 and reverted -// in v2.4.0, at which point this function was introduced to help migration. -func FutureLineWrap() { - disableLineWrapping = true -} diff --git a/vendor/gopkg.in/yaml.v2/yamlh.go b/vendor/gopkg.in/yaml.v2/yamlh.go deleted file mode 100644 index f6a9c8e34b..0000000000 --- a/vendor/gopkg.in/yaml.v2/yamlh.go +++ /dev/null @@ -1,739 +0,0 @@ -package yaml - -import ( - "fmt" - "io" -) - -// The version directive data. -type yaml_version_directive_t struct { - major int8 // The major version number. - minor int8 // The minor version number. -} - -// The tag directive data. -type yaml_tag_directive_t struct { - handle []byte // The tag handle. - prefix []byte // The tag prefix. -} - -type yaml_encoding_t int - -// The stream encoding. -const ( - // Let the parser choose the encoding. - yaml_ANY_ENCODING yaml_encoding_t = iota - - yaml_UTF8_ENCODING // The default UTF-8 encoding. - yaml_UTF16LE_ENCODING // The UTF-16-LE encoding with BOM. - yaml_UTF16BE_ENCODING // The UTF-16-BE encoding with BOM. -) - -type yaml_break_t int - -// Line break types. -const ( - // Let the parser choose the break type. - yaml_ANY_BREAK yaml_break_t = iota - - yaml_CR_BREAK // Use CR for line breaks (Mac style). - yaml_LN_BREAK // Use LN for line breaks (Unix style). - yaml_CRLN_BREAK // Use CR LN for line breaks (DOS style). -) - -type yaml_error_type_t int - -// Many bad things could happen with the parser and emitter. -const ( - // No error is produced. - yaml_NO_ERROR yaml_error_type_t = iota - - yaml_MEMORY_ERROR // Cannot allocate or reallocate a block of memory. - yaml_READER_ERROR // Cannot read or decode the input stream. - yaml_SCANNER_ERROR // Cannot scan the input stream. - yaml_PARSER_ERROR // Cannot parse the input stream. - yaml_COMPOSER_ERROR // Cannot compose a YAML document. - yaml_WRITER_ERROR // Cannot write to the output stream. - yaml_EMITTER_ERROR // Cannot emit a YAML stream. -) - -// The pointer position. -type yaml_mark_t struct { - index int // The position index. - line int // The position line. - column int // The position column. -} - -// Node Styles - -type yaml_style_t int8 - -type yaml_scalar_style_t yaml_style_t - -// Scalar styles. -const ( - // Let the emitter choose the style. - yaml_ANY_SCALAR_STYLE yaml_scalar_style_t = iota - - yaml_PLAIN_SCALAR_STYLE // The plain scalar style. - yaml_SINGLE_QUOTED_SCALAR_STYLE // The single-quoted scalar style. - yaml_DOUBLE_QUOTED_SCALAR_STYLE // The double-quoted scalar style. - yaml_LITERAL_SCALAR_STYLE // The literal scalar style. - yaml_FOLDED_SCALAR_STYLE // The folded scalar style. -) - -type yaml_sequence_style_t yaml_style_t - -// Sequence styles. -const ( - // Let the emitter choose the style. - yaml_ANY_SEQUENCE_STYLE yaml_sequence_style_t = iota - - yaml_BLOCK_SEQUENCE_STYLE // The block sequence style. - yaml_FLOW_SEQUENCE_STYLE // The flow sequence style. -) - -type yaml_mapping_style_t yaml_style_t - -// Mapping styles. -const ( - // Let the emitter choose the style. - yaml_ANY_MAPPING_STYLE yaml_mapping_style_t = iota - - yaml_BLOCK_MAPPING_STYLE // The block mapping style. - yaml_FLOW_MAPPING_STYLE // The flow mapping style. -) - -// Tokens - -type yaml_token_type_t int - -// Token types. -const ( - // An empty token. - yaml_NO_TOKEN yaml_token_type_t = iota - - yaml_STREAM_START_TOKEN // A STREAM-START token. - yaml_STREAM_END_TOKEN // A STREAM-END token. - - yaml_VERSION_DIRECTIVE_TOKEN // A VERSION-DIRECTIVE token. - yaml_TAG_DIRECTIVE_TOKEN // A TAG-DIRECTIVE token. - yaml_DOCUMENT_START_TOKEN // A DOCUMENT-START token. - yaml_DOCUMENT_END_TOKEN // A DOCUMENT-END token. - - yaml_BLOCK_SEQUENCE_START_TOKEN // A BLOCK-SEQUENCE-START token. - yaml_BLOCK_MAPPING_START_TOKEN // A BLOCK-SEQUENCE-END token. - yaml_BLOCK_END_TOKEN // A BLOCK-END token. - - yaml_FLOW_SEQUENCE_START_TOKEN // A FLOW-SEQUENCE-START token. - yaml_FLOW_SEQUENCE_END_TOKEN // A FLOW-SEQUENCE-END token. - yaml_FLOW_MAPPING_START_TOKEN // A FLOW-MAPPING-START token. - yaml_FLOW_MAPPING_END_TOKEN // A FLOW-MAPPING-END token. - - yaml_BLOCK_ENTRY_TOKEN // A BLOCK-ENTRY token. - yaml_FLOW_ENTRY_TOKEN // A FLOW-ENTRY token. - yaml_KEY_TOKEN // A KEY token. - yaml_VALUE_TOKEN // A VALUE token. - - yaml_ALIAS_TOKEN // An ALIAS token. - yaml_ANCHOR_TOKEN // An ANCHOR token. - yaml_TAG_TOKEN // A TAG token. - yaml_SCALAR_TOKEN // A SCALAR token. -) - -func (tt yaml_token_type_t) String() string { - switch tt { - case yaml_NO_TOKEN: - return "yaml_NO_TOKEN" - case yaml_STREAM_START_TOKEN: - return "yaml_STREAM_START_TOKEN" - case yaml_STREAM_END_TOKEN: - return "yaml_STREAM_END_TOKEN" - case yaml_VERSION_DIRECTIVE_TOKEN: - return "yaml_VERSION_DIRECTIVE_TOKEN" - case yaml_TAG_DIRECTIVE_TOKEN: - return "yaml_TAG_DIRECTIVE_TOKEN" - case yaml_DOCUMENT_START_TOKEN: - return "yaml_DOCUMENT_START_TOKEN" - case yaml_DOCUMENT_END_TOKEN: - return "yaml_DOCUMENT_END_TOKEN" - case yaml_BLOCK_SEQUENCE_START_TOKEN: - return "yaml_BLOCK_SEQUENCE_START_TOKEN" - case yaml_BLOCK_MAPPING_START_TOKEN: - return "yaml_BLOCK_MAPPING_START_TOKEN" - case yaml_BLOCK_END_TOKEN: - return "yaml_BLOCK_END_TOKEN" - case yaml_FLOW_SEQUENCE_START_TOKEN: - return "yaml_FLOW_SEQUENCE_START_TOKEN" - case yaml_FLOW_SEQUENCE_END_TOKEN: - return "yaml_FLOW_SEQUENCE_END_TOKEN" - case yaml_FLOW_MAPPING_START_TOKEN: - return "yaml_FLOW_MAPPING_START_TOKEN" - case yaml_FLOW_MAPPING_END_TOKEN: - return "yaml_FLOW_MAPPING_END_TOKEN" - case yaml_BLOCK_ENTRY_TOKEN: - return "yaml_BLOCK_ENTRY_TOKEN" - case yaml_FLOW_ENTRY_TOKEN: - return "yaml_FLOW_ENTRY_TOKEN" - case yaml_KEY_TOKEN: - return "yaml_KEY_TOKEN" - case yaml_VALUE_TOKEN: - return "yaml_VALUE_TOKEN" - case yaml_ALIAS_TOKEN: - return "yaml_ALIAS_TOKEN" - case yaml_ANCHOR_TOKEN: - return "yaml_ANCHOR_TOKEN" - case yaml_TAG_TOKEN: - return "yaml_TAG_TOKEN" - case yaml_SCALAR_TOKEN: - return "yaml_SCALAR_TOKEN" - } - return "" -} - -// The token structure. -type yaml_token_t struct { - // The token type. - typ yaml_token_type_t - - // The start/end of the token. - start_mark, end_mark yaml_mark_t - - // The stream encoding (for yaml_STREAM_START_TOKEN). - encoding yaml_encoding_t - - // The alias/anchor/scalar value or tag/tag directive handle - // (for yaml_ALIAS_TOKEN, yaml_ANCHOR_TOKEN, yaml_SCALAR_TOKEN, yaml_TAG_TOKEN, yaml_TAG_DIRECTIVE_TOKEN). - value []byte - - // The tag suffix (for yaml_TAG_TOKEN). - suffix []byte - - // The tag directive prefix (for yaml_TAG_DIRECTIVE_TOKEN). - prefix []byte - - // The scalar style (for yaml_SCALAR_TOKEN). - style yaml_scalar_style_t - - // The version directive major/minor (for yaml_VERSION_DIRECTIVE_TOKEN). - major, minor int8 -} - -// Events - -type yaml_event_type_t int8 - -// Event types. -const ( - // An empty event. - yaml_NO_EVENT yaml_event_type_t = iota - - yaml_STREAM_START_EVENT // A STREAM-START event. - yaml_STREAM_END_EVENT // A STREAM-END event. - yaml_DOCUMENT_START_EVENT // A DOCUMENT-START event. - yaml_DOCUMENT_END_EVENT // A DOCUMENT-END event. - yaml_ALIAS_EVENT // An ALIAS event. - yaml_SCALAR_EVENT // A SCALAR event. - yaml_SEQUENCE_START_EVENT // A SEQUENCE-START event. - yaml_SEQUENCE_END_EVENT // A SEQUENCE-END event. - yaml_MAPPING_START_EVENT // A MAPPING-START event. - yaml_MAPPING_END_EVENT // A MAPPING-END event. -) - -var eventStrings = []string{ - yaml_NO_EVENT: "none", - yaml_STREAM_START_EVENT: "stream start", - yaml_STREAM_END_EVENT: "stream end", - yaml_DOCUMENT_START_EVENT: "document start", - yaml_DOCUMENT_END_EVENT: "document end", - yaml_ALIAS_EVENT: "alias", - yaml_SCALAR_EVENT: "scalar", - yaml_SEQUENCE_START_EVENT: "sequence start", - yaml_SEQUENCE_END_EVENT: "sequence end", - yaml_MAPPING_START_EVENT: "mapping start", - yaml_MAPPING_END_EVENT: "mapping end", -} - -func (e yaml_event_type_t) String() string { - if e < 0 || int(e) >= len(eventStrings) { - return fmt.Sprintf("unknown event %d", e) - } - return eventStrings[e] -} - -// The event structure. -type yaml_event_t struct { - - // The event type. - typ yaml_event_type_t - - // The start and end of the event. - start_mark, end_mark yaml_mark_t - - // The document encoding (for yaml_STREAM_START_EVENT). - encoding yaml_encoding_t - - // The version directive (for yaml_DOCUMENT_START_EVENT). - version_directive *yaml_version_directive_t - - // The list of tag directives (for yaml_DOCUMENT_START_EVENT). - tag_directives []yaml_tag_directive_t - - // The anchor (for yaml_SCALAR_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT, yaml_ALIAS_EVENT). - anchor []byte - - // The tag (for yaml_SCALAR_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT). - tag []byte - - // The scalar value (for yaml_SCALAR_EVENT). - value []byte - - // Is the document start/end indicator implicit, or the tag optional? - // (for yaml_DOCUMENT_START_EVENT, yaml_DOCUMENT_END_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT, yaml_SCALAR_EVENT). - implicit bool - - // Is the tag optional for any non-plain style? (for yaml_SCALAR_EVENT). - quoted_implicit bool - - // The style (for yaml_SCALAR_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT). - style yaml_style_t -} - -func (e *yaml_event_t) scalar_style() yaml_scalar_style_t { return yaml_scalar_style_t(e.style) } -func (e *yaml_event_t) sequence_style() yaml_sequence_style_t { return yaml_sequence_style_t(e.style) } -func (e *yaml_event_t) mapping_style() yaml_mapping_style_t { return yaml_mapping_style_t(e.style) } - -// Nodes - -const ( - yaml_NULL_TAG = "tag:yaml.org,2002:null" // The tag !!null with the only possible value: null. - yaml_BOOL_TAG = "tag:yaml.org,2002:bool" // The tag !!bool with the values: true and false. - yaml_STR_TAG = "tag:yaml.org,2002:str" // The tag !!str for string values. - yaml_INT_TAG = "tag:yaml.org,2002:int" // The tag !!int for integer values. - yaml_FLOAT_TAG = "tag:yaml.org,2002:float" // The tag !!float for float values. - yaml_TIMESTAMP_TAG = "tag:yaml.org,2002:timestamp" // The tag !!timestamp for date and time values. - - yaml_SEQ_TAG = "tag:yaml.org,2002:seq" // The tag !!seq is used to denote sequences. - yaml_MAP_TAG = "tag:yaml.org,2002:map" // The tag !!map is used to denote mapping. - - // Not in original libyaml. - yaml_BINARY_TAG = "tag:yaml.org,2002:binary" - yaml_MERGE_TAG = "tag:yaml.org,2002:merge" - - yaml_DEFAULT_SCALAR_TAG = yaml_STR_TAG // The default scalar tag is !!str. - yaml_DEFAULT_SEQUENCE_TAG = yaml_SEQ_TAG // The default sequence tag is !!seq. - yaml_DEFAULT_MAPPING_TAG = yaml_MAP_TAG // The default mapping tag is !!map. -) - -type yaml_node_type_t int - -// Node types. -const ( - // An empty node. - yaml_NO_NODE yaml_node_type_t = iota - - yaml_SCALAR_NODE // A scalar node. - yaml_SEQUENCE_NODE // A sequence node. - yaml_MAPPING_NODE // A mapping node. -) - -// An element of a sequence node. -type yaml_node_item_t int - -// An element of a mapping node. -type yaml_node_pair_t struct { - key int // The key of the element. - value int // The value of the element. -} - -// The node structure. -type yaml_node_t struct { - typ yaml_node_type_t // The node type. - tag []byte // The node tag. - - // The node data. - - // The scalar parameters (for yaml_SCALAR_NODE). - scalar struct { - value []byte // The scalar value. - length int // The length of the scalar value. - style yaml_scalar_style_t // The scalar style. - } - - // The sequence parameters (for YAML_SEQUENCE_NODE). - sequence struct { - items_data []yaml_node_item_t // The stack of sequence items. - style yaml_sequence_style_t // The sequence style. - } - - // The mapping parameters (for yaml_MAPPING_NODE). - mapping struct { - pairs_data []yaml_node_pair_t // The stack of mapping pairs (key, value). - pairs_start *yaml_node_pair_t // The beginning of the stack. - pairs_end *yaml_node_pair_t // The end of the stack. - pairs_top *yaml_node_pair_t // The top of the stack. - style yaml_mapping_style_t // The mapping style. - } - - start_mark yaml_mark_t // The beginning of the node. - end_mark yaml_mark_t // The end of the node. - -} - -// The document structure. -type yaml_document_t struct { - - // The document nodes. - nodes []yaml_node_t - - // The version directive. - version_directive *yaml_version_directive_t - - // The list of tag directives. - tag_directives_data []yaml_tag_directive_t - tag_directives_start int // The beginning of the tag directives list. - tag_directives_end int // The end of the tag directives list. - - start_implicit int // Is the document start indicator implicit? - end_implicit int // Is the document end indicator implicit? - - // The start/end of the document. - start_mark, end_mark yaml_mark_t -} - -// The prototype of a read handler. -// -// The read handler is called when the parser needs to read more bytes from the -// source. The handler should write not more than size bytes to the buffer. -// The number of written bytes should be set to the size_read variable. -// -// [in,out] data A pointer to an application data specified by -// yaml_parser_set_input(). -// [out] buffer The buffer to write the data from the source. -// [in] size The size of the buffer. -// [out] size_read The actual number of bytes read from the source. -// -// On success, the handler should return 1. If the handler failed, -// the returned value should be 0. On EOF, the handler should set the -// size_read to 0 and return 1. -type yaml_read_handler_t func(parser *yaml_parser_t, buffer []byte) (n int, err error) - -// This structure holds information about a potential simple key. -type yaml_simple_key_t struct { - possible bool // Is a simple key possible? - required bool // Is a simple key required? - token_number int // The number of the token. - mark yaml_mark_t // The position mark. -} - -// The states of the parser. -type yaml_parser_state_t int - -const ( - yaml_PARSE_STREAM_START_STATE yaml_parser_state_t = iota - - yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE // Expect the beginning of an implicit document. - yaml_PARSE_DOCUMENT_START_STATE // Expect DOCUMENT-START. - yaml_PARSE_DOCUMENT_CONTENT_STATE // Expect the content of a document. - yaml_PARSE_DOCUMENT_END_STATE // Expect DOCUMENT-END. - yaml_PARSE_BLOCK_NODE_STATE // Expect a block node. - yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE // Expect a block node or indentless sequence. - yaml_PARSE_FLOW_NODE_STATE // Expect a flow node. - yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE // Expect the first entry of a block sequence. - yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE // Expect an entry of a block sequence. - yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE // Expect an entry of an indentless sequence. - yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE // Expect the first key of a block mapping. - yaml_PARSE_BLOCK_MAPPING_KEY_STATE // Expect a block mapping key. - yaml_PARSE_BLOCK_MAPPING_VALUE_STATE // Expect a block mapping value. - yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE // Expect the first entry of a flow sequence. - yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE // Expect an entry of a flow sequence. - yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE // Expect a key of an ordered mapping. - yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE // Expect a value of an ordered mapping. - yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE // Expect the and of an ordered mapping entry. - yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE // Expect the first key of a flow mapping. - yaml_PARSE_FLOW_MAPPING_KEY_STATE // Expect a key of a flow mapping. - yaml_PARSE_FLOW_MAPPING_VALUE_STATE // Expect a value of a flow mapping. - yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE // Expect an empty value of a flow mapping. - yaml_PARSE_END_STATE // Expect nothing. -) - -func (ps yaml_parser_state_t) String() string { - switch ps { - case yaml_PARSE_STREAM_START_STATE: - return "yaml_PARSE_STREAM_START_STATE" - case yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE: - return "yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE" - case yaml_PARSE_DOCUMENT_START_STATE: - return "yaml_PARSE_DOCUMENT_START_STATE" - case yaml_PARSE_DOCUMENT_CONTENT_STATE: - return "yaml_PARSE_DOCUMENT_CONTENT_STATE" - case yaml_PARSE_DOCUMENT_END_STATE: - return "yaml_PARSE_DOCUMENT_END_STATE" - case yaml_PARSE_BLOCK_NODE_STATE: - return "yaml_PARSE_BLOCK_NODE_STATE" - case yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE: - return "yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE" - case yaml_PARSE_FLOW_NODE_STATE: - return "yaml_PARSE_FLOW_NODE_STATE" - case yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE: - return "yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE" - case yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE: - return "yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE" - case yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE: - return "yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE" - case yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE: - return "yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE" - case yaml_PARSE_BLOCK_MAPPING_KEY_STATE: - return "yaml_PARSE_BLOCK_MAPPING_KEY_STATE" - case yaml_PARSE_BLOCK_MAPPING_VALUE_STATE: - return "yaml_PARSE_BLOCK_MAPPING_VALUE_STATE" - case yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE: - return "yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE" - case yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE: - return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE" - case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE: - return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE" - case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE: - return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE" - case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE: - return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE" - case yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE: - return "yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE" - case yaml_PARSE_FLOW_MAPPING_KEY_STATE: - return "yaml_PARSE_FLOW_MAPPING_KEY_STATE" - case yaml_PARSE_FLOW_MAPPING_VALUE_STATE: - return "yaml_PARSE_FLOW_MAPPING_VALUE_STATE" - case yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE: - return "yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE" - case yaml_PARSE_END_STATE: - return "yaml_PARSE_END_STATE" - } - return "" -} - -// This structure holds aliases data. -type yaml_alias_data_t struct { - anchor []byte // The anchor. - index int // The node id. - mark yaml_mark_t // The anchor mark. -} - -// The parser structure. -// -// All members are internal. Manage the structure using the -// yaml_parser_ family of functions. -type yaml_parser_t struct { - - // Error handling - - error yaml_error_type_t // Error type. - - problem string // Error description. - - // The byte about which the problem occurred. - problem_offset int - problem_value int - problem_mark yaml_mark_t - - // The error context. - context string - context_mark yaml_mark_t - - // Reader stuff - - read_handler yaml_read_handler_t // Read handler. - - input_reader io.Reader // File input data. - input []byte // String input data. - input_pos int - - eof bool // EOF flag - - buffer []byte // The working buffer. - buffer_pos int // The current position of the buffer. - - unread int // The number of unread characters in the buffer. - - raw_buffer []byte // The raw buffer. - raw_buffer_pos int // The current position of the buffer. - - encoding yaml_encoding_t // The input encoding. - - offset int // The offset of the current position (in bytes). - mark yaml_mark_t // The mark of the current position. - - // Scanner stuff - - stream_start_produced bool // Have we started to scan the input stream? - stream_end_produced bool // Have we reached the end of the input stream? - - flow_level int // The number of unclosed '[' and '{' indicators. - - tokens []yaml_token_t // The tokens queue. - tokens_head int // The head of the tokens queue. - tokens_parsed int // The number of tokens fetched from the queue. - token_available bool // Does the tokens queue contain a token ready for dequeueing. - - indent int // The current indentation level. - indents []int // The indentation levels stack. - - simple_key_allowed bool // May a simple key occur at the current position? - simple_keys []yaml_simple_key_t // The stack of simple keys. - simple_keys_by_tok map[int]int // possible simple_key indexes indexed by token_number - - // Parser stuff - - state yaml_parser_state_t // The current parser state. - states []yaml_parser_state_t // The parser states stack. - marks []yaml_mark_t // The stack of marks. - tag_directives []yaml_tag_directive_t // The list of TAG directives. - - // Dumper stuff - - aliases []yaml_alias_data_t // The alias data. - - document *yaml_document_t // The currently parsed document. -} - -// Emitter Definitions - -// The prototype of a write handler. -// -// The write handler is called when the emitter needs to flush the accumulated -// characters to the output. The handler should write @a size bytes of the -// @a buffer to the output. -// -// @param[in,out] data A pointer to an application data specified by -// yaml_emitter_set_output(). -// @param[in] buffer The buffer with bytes to be written. -// @param[in] size The size of the buffer. -// -// @returns On success, the handler should return @c 1. If the handler failed, -// the returned value should be @c 0. -// -type yaml_write_handler_t func(emitter *yaml_emitter_t, buffer []byte) error - -type yaml_emitter_state_t int - -// The emitter states. -const ( - // Expect STREAM-START. - yaml_EMIT_STREAM_START_STATE yaml_emitter_state_t = iota - - yaml_EMIT_FIRST_DOCUMENT_START_STATE // Expect the first DOCUMENT-START or STREAM-END. - yaml_EMIT_DOCUMENT_START_STATE // Expect DOCUMENT-START or STREAM-END. - yaml_EMIT_DOCUMENT_CONTENT_STATE // Expect the content of a document. - yaml_EMIT_DOCUMENT_END_STATE // Expect DOCUMENT-END. - yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE // Expect the first item of a flow sequence. - yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE // Expect an item of a flow sequence. - yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE // Expect the first key of a flow mapping. - yaml_EMIT_FLOW_MAPPING_KEY_STATE // Expect a key of a flow mapping. - yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE // Expect a value for a simple key of a flow mapping. - yaml_EMIT_FLOW_MAPPING_VALUE_STATE // Expect a value of a flow mapping. - yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE // Expect the first item of a block sequence. - yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE // Expect an item of a block sequence. - yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE // Expect the first key of a block mapping. - yaml_EMIT_BLOCK_MAPPING_KEY_STATE // Expect the key of a block mapping. - yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE // Expect a value for a simple key of a block mapping. - yaml_EMIT_BLOCK_MAPPING_VALUE_STATE // Expect a value of a block mapping. - yaml_EMIT_END_STATE // Expect nothing. -) - -// The emitter structure. -// -// All members are internal. Manage the structure using the @c yaml_emitter_ -// family of functions. -type yaml_emitter_t struct { - - // Error handling - - error yaml_error_type_t // Error type. - problem string // Error description. - - // Writer stuff - - write_handler yaml_write_handler_t // Write handler. - - output_buffer *[]byte // String output data. - output_writer io.Writer // File output data. - - buffer []byte // The working buffer. - buffer_pos int // The current position of the buffer. - - raw_buffer []byte // The raw buffer. - raw_buffer_pos int // The current position of the buffer. - - encoding yaml_encoding_t // The stream encoding. - - // Emitter stuff - - canonical bool // If the output is in the canonical style? - best_indent int // The number of indentation spaces. - best_width int // The preferred width of the output lines. - unicode bool // Allow unescaped non-ASCII characters? - line_break yaml_break_t // The preferred line break. - - state yaml_emitter_state_t // The current emitter state. - states []yaml_emitter_state_t // The stack of states. - - events []yaml_event_t // The event queue. - events_head int // The head of the event queue. - - indents []int // The stack of indentation levels. - - tag_directives []yaml_tag_directive_t // The list of tag directives. - - indent int // The current indentation level. - - flow_level int // The current flow level. - - root_context bool // Is it the document root context? - sequence_context bool // Is it a sequence context? - mapping_context bool // Is it a mapping context? - simple_key_context bool // Is it a simple mapping key context? - - line int // The current line. - column int // The current column. - whitespace bool // If the last character was a whitespace? - indention bool // If the last character was an indentation character (' ', '-', '?', ':')? - open_ended bool // If an explicit document end is required? - - // Anchor analysis. - anchor_data struct { - anchor []byte // The anchor value. - alias bool // Is it an alias? - } - - // Tag analysis. - tag_data struct { - handle []byte // The tag handle. - suffix []byte // The tag suffix. - } - - // Scalar analysis. - scalar_data struct { - value []byte // The scalar value. - multiline bool // Does the scalar contain line breaks? - flow_plain_allowed bool // Can the scalar be expessed in the flow plain style? - block_plain_allowed bool // Can the scalar be expressed in the block plain style? - single_quoted_allowed bool // Can the scalar be expressed in the single quoted style? - block_allowed bool // Can the scalar be expressed in the literal or folded styles? - style yaml_scalar_style_t // The output style. - } - - // Dumper stuff - - opened bool // If the stream was already opened? - closed bool // If the stream was already closed? - - // The information associated with the document nodes. - anchors *struct { - references int // The number of references. - anchor int // The anchor id. - serialized bool // If the node has been emitted? - } - - last_anchor_id int // The last assigned anchor id. - - document *yaml_document_t // The currently emitted document. -} diff --git a/vendor/gopkg.in/yaml.v2/yamlprivateh.go b/vendor/gopkg.in/yaml.v2/yamlprivateh.go deleted file mode 100644 index 8110ce3c37..0000000000 --- a/vendor/gopkg.in/yaml.v2/yamlprivateh.go +++ /dev/null @@ -1,173 +0,0 @@ -package yaml - -const ( - // The size of the input raw buffer. - input_raw_buffer_size = 512 - - // The size of the input buffer. - // It should be possible to decode the whole raw buffer. - input_buffer_size = input_raw_buffer_size * 3 - - // The size of the output buffer. - output_buffer_size = 128 - - // The size of the output raw buffer. - // It should be possible to encode the whole output buffer. - output_raw_buffer_size = (output_buffer_size*2 + 2) - - // The size of other stacks and queues. - initial_stack_size = 16 - initial_queue_size = 16 - initial_string_size = 16 -) - -// Check if the character at the specified position is an alphabetical -// character, a digit, '_', or '-'. -func is_alpha(b []byte, i int) bool { - return b[i] >= '0' && b[i] <= '9' || b[i] >= 'A' && b[i] <= 'Z' || b[i] >= 'a' && b[i] <= 'z' || b[i] == '_' || b[i] == '-' -} - -// Check if the character at the specified position is a digit. -func is_digit(b []byte, i int) bool { - return b[i] >= '0' && b[i] <= '9' -} - -// Get the value of a digit. -func as_digit(b []byte, i int) int { - return int(b[i]) - '0' -} - -// Check if the character at the specified position is a hex-digit. -func is_hex(b []byte, i int) bool { - return b[i] >= '0' && b[i] <= '9' || b[i] >= 'A' && b[i] <= 'F' || b[i] >= 'a' && b[i] <= 'f' -} - -// Get the value of a hex-digit. -func as_hex(b []byte, i int) int { - bi := b[i] - if bi >= 'A' && bi <= 'F' { - return int(bi) - 'A' + 10 - } - if bi >= 'a' && bi <= 'f' { - return int(bi) - 'a' + 10 - } - return int(bi) - '0' -} - -// Check if the character is ASCII. -func is_ascii(b []byte, i int) bool { - return b[i] <= 0x7F -} - -// Check if the character at the start of the buffer can be printed unescaped. -func is_printable(b []byte, i int) bool { - return ((b[i] == 0x0A) || // . == #x0A - (b[i] >= 0x20 && b[i] <= 0x7E) || // #x20 <= . <= #x7E - (b[i] == 0xC2 && b[i+1] >= 0xA0) || // #0xA0 <= . <= #xD7FF - (b[i] > 0xC2 && b[i] < 0xED) || - (b[i] == 0xED && b[i+1] < 0xA0) || - (b[i] == 0xEE) || - (b[i] == 0xEF && // #xE000 <= . <= #xFFFD - !(b[i+1] == 0xBB && b[i+2] == 0xBF) && // && . != #xFEFF - !(b[i+1] == 0xBF && (b[i+2] == 0xBE || b[i+2] == 0xBF)))) -} - -// Check if the character at the specified position is NUL. -func is_z(b []byte, i int) bool { - return b[i] == 0x00 -} - -// Check if the beginning of the buffer is a BOM. -func is_bom(b []byte, i int) bool { - return b[0] == 0xEF && b[1] == 0xBB && b[2] == 0xBF -} - -// Check if the character at the specified position is space. -func is_space(b []byte, i int) bool { - return b[i] == ' ' -} - -// Check if the character at the specified position is tab. -func is_tab(b []byte, i int) bool { - return b[i] == '\t' -} - -// Check if the character at the specified position is blank (space or tab). -func is_blank(b []byte, i int) bool { - //return is_space(b, i) || is_tab(b, i) - return b[i] == ' ' || b[i] == '\t' -} - -// Check if the character at the specified position is a line break. -func is_break(b []byte, i int) bool { - return (b[i] == '\r' || // CR (#xD) - b[i] == '\n' || // LF (#xA) - b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85) - b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028) - b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9) // PS (#x2029) -} - -func is_crlf(b []byte, i int) bool { - return b[i] == '\r' && b[i+1] == '\n' -} - -// Check if the character is a line break or NUL. -func is_breakz(b []byte, i int) bool { - //return is_break(b, i) || is_z(b, i) - return ( // is_break: - b[i] == '\r' || // CR (#xD) - b[i] == '\n' || // LF (#xA) - b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85) - b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028) - b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029) - // is_z: - b[i] == 0) -} - -// Check if the character is a line break, space, or NUL. -func is_spacez(b []byte, i int) bool { - //return is_space(b, i) || is_breakz(b, i) - return ( // is_space: - b[i] == ' ' || - // is_breakz: - b[i] == '\r' || // CR (#xD) - b[i] == '\n' || // LF (#xA) - b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85) - b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028) - b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029) - b[i] == 0) -} - -// Check if the character is a line break, space, tab, or NUL. -func is_blankz(b []byte, i int) bool { - //return is_blank(b, i) || is_breakz(b, i) - return ( // is_blank: - b[i] == ' ' || b[i] == '\t' || - // is_breakz: - b[i] == '\r' || // CR (#xD) - b[i] == '\n' || // LF (#xA) - b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85) - b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028) - b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029) - b[i] == 0) -} - -// Determine the width of the character. -func width(b byte) int { - // Don't replace these by a switch without first - // confirming that it is being inlined. - if b&0x80 == 0x00 { - return 1 - } - if b&0xE0 == 0xC0 { - return 2 - } - if b&0xF0 == 0xE0 { - return 3 - } - if b&0xF8 == 0xF0 { - return 4 - } - return 0 - -} diff --git a/vendor/howett.net/plist/.gitlab-ci.yml b/vendor/howett.net/plist/.gitlab-ci.yml deleted file mode 100644 index 11d6dbf73e..0000000000 --- a/vendor/howett.net/plist/.gitlab-ci.yml +++ /dev/null @@ -1,39 +0,0 @@ -image: golang:alpine -stages: - - test - -variables: - GO_PACKAGE: "howett.net/plist" - -before_script: - - "mkdir -p $(dirname $GOPATH/src/$GO_PACKAGE)" - - "ln -s $(pwd) $GOPATH/src/$GO_PACKAGE" - - "cd $GOPATH/src/$GO_PACKAGE" - -.template:go-test: &template-go-test - stage: test - script: - - go test - -go-test-cover:latest: - stage: test - script: - - go test -v -cover - coverage: '/^coverage: \d+\.\d+/' - -go-test-appengine:latest: - stage: test - script: - - go test -tags appengine - -go-test:1.6: - <<: *template-go-test - image: golang:1.6-alpine - -go-test:1.4: - <<: *template-go-test - image: golang:1.4-alpine - -go-test:1.2: - <<: *template-go-test - image: golang:1.2 diff --git a/vendor/howett.net/plist/LICENSE b/vendor/howett.net/plist/LICENSE deleted file mode 100644 index 9f6012f32b..0000000000 --- a/vendor/howett.net/plist/LICENSE +++ /dev/null @@ -1,58 +0,0 @@ -Copyright (c) 2013, Dustin L. Howett. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the FreeBSD Project. - --------------------------------------------------------------------------------- -Parts of this package were made available under the license covering -the Go language and all attended core libraries. That license follows. --------------------------------------------------------------------------------- - -Copyright (c) 2012 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/howett.net/plist/README.md b/vendor/howett.net/plist/README.md deleted file mode 100644 index a13e29a388..0000000000 --- a/vendor/howett.net/plist/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# plist - A pure Go property list transcoder [![coverage report](https://gitlab.howett.net/go/plist/badges/master/coverage.svg)](https://gitlab.howett.net/go/plist/commits/master) -## INSTALL -``` -$ go get howett.net/plist -``` - -## FEATURES -* Supports encoding/decoding property lists (Apple XML, Apple Binary, OpenStep and GNUStep) from/to arbitrary Go types - -## USE -```go -package main -import ( - "howett.net/plist" - "os" -) -func main() { - encoder := plist.NewEncoder(os.Stdout) - encoder.Encode(map[string]string{"hello": "world"}) -} -``` diff --git a/vendor/howett.net/plist/bplist.go b/vendor/howett.net/plist/bplist.go deleted file mode 100644 index 962793a9f2..0000000000 --- a/vendor/howett.net/plist/bplist.go +++ /dev/null @@ -1,26 +0,0 @@ -package plist - -type bplistTrailer struct { - Unused [5]uint8 - SortVersion uint8 - OffsetIntSize uint8 - ObjectRefSize uint8 - NumObjects uint64 - TopObject uint64 - OffsetTableOffset uint64 -} - -const ( - bpTagNull uint8 = 0x00 - bpTagBoolFalse = 0x08 - bpTagBoolTrue = 0x09 - bpTagInteger = 0x10 - bpTagReal = 0x20 - bpTagDate = 0x30 - bpTagData = 0x40 - bpTagASCIIString = 0x50 - bpTagUTF16String = 0x60 - bpTagUID = 0x80 - bpTagArray = 0xA0 - bpTagDictionary = 0xD0 -) diff --git a/vendor/howett.net/plist/bplist_generator.go b/vendor/howett.net/plist/bplist_generator.go deleted file mode 100644 index 09ab71b1f4..0000000000 --- a/vendor/howett.net/plist/bplist_generator.go +++ /dev/null @@ -1,303 +0,0 @@ -package plist - -import ( - "encoding/binary" - "errors" - "fmt" - "io" - "time" - "unicode/utf16" -) - -func bplistMinimumIntSize(n uint64) int { - switch { - case n <= uint64(0xff): - return 1 - case n <= uint64(0xffff): - return 2 - case n <= uint64(0xffffffff): - return 4 - default: - return 8 - } -} - -func bplistValueShouldUnique(pval cfValue) bool { - switch pval.(type) { - case cfString, *cfNumber, *cfReal, cfDate, cfData: - return true - } - return false -} - -type bplistGenerator struct { - writer *countedWriter - objmap map[interface{}]uint64 // maps pValue.hash()es to object locations - objtable []cfValue - trailer bplistTrailer -} - -func (p *bplistGenerator) flattenPlistValue(pval cfValue) { - key := pval.hash() - if bplistValueShouldUnique(pval) { - if _, ok := p.objmap[key]; ok { - return - } - } - - p.objmap[key] = uint64(len(p.objtable)) - p.objtable = append(p.objtable, pval) - - switch pval := pval.(type) { - case *cfDictionary: - pval.sort() - for _, k := range pval.keys { - p.flattenPlistValue(cfString(k)) - } - for _, v := range pval.values { - p.flattenPlistValue(v) - } - case *cfArray: - for _, v := range pval.values { - p.flattenPlistValue(v) - } - } -} - -func (p *bplistGenerator) indexForPlistValue(pval cfValue) (uint64, bool) { - v, ok := p.objmap[pval.hash()] - return v, ok -} - -func (p *bplistGenerator) generateDocument(root cfValue) { - p.objtable = make([]cfValue, 0, 16) - p.objmap = make(map[interface{}]uint64) - p.flattenPlistValue(root) - - p.trailer.NumObjects = uint64(len(p.objtable)) - p.trailer.ObjectRefSize = uint8(bplistMinimumIntSize(p.trailer.NumObjects)) - - p.writer.Write([]byte("bplist00")) - - offtable := make([]uint64, p.trailer.NumObjects) - for i, pval := range p.objtable { - offtable[i] = uint64(p.writer.BytesWritten()) - p.writePlistValue(pval) - } - - p.trailer.OffsetIntSize = uint8(bplistMinimumIntSize(uint64(p.writer.BytesWritten()))) - p.trailer.TopObject = p.objmap[root.hash()] - p.trailer.OffsetTableOffset = uint64(p.writer.BytesWritten()) - - for _, offset := range offtable { - p.writeSizedInt(offset, int(p.trailer.OffsetIntSize)) - } - - binary.Write(p.writer, binary.BigEndian, p.trailer) -} - -func (p *bplistGenerator) writePlistValue(pval cfValue) { - if pval == nil { - return - } - - switch pval := pval.(type) { - case *cfDictionary: - p.writeDictionaryTag(pval) - case *cfArray: - p.writeArrayTag(pval.values) - case cfString: - p.writeStringTag(string(pval)) - case *cfNumber: - p.writeIntTag(pval.signed, pval.value) - case *cfReal: - if pval.wide { - p.writeRealTag(pval.value, 64) - } else { - p.writeRealTag(pval.value, 32) - } - case cfBoolean: - p.writeBoolTag(bool(pval)) - case cfData: - p.writeDataTag([]byte(pval)) - case cfDate: - p.writeDateTag(time.Time(pval)) - case cfUID: - p.writeUIDTag(UID(pval)) - default: - panic(fmt.Errorf("unknown plist type %t", pval)) - } -} - -func (p *bplistGenerator) writeSizedInt(n uint64, nbytes int) { - var val interface{} - switch nbytes { - case 1: - val = uint8(n) - case 2: - val = uint16(n) - case 4: - val = uint32(n) - case 8: - val = n - default: - panic(errors.New("illegal integer size")) - } - binary.Write(p.writer, binary.BigEndian, val) -} - -func (p *bplistGenerator) writeBoolTag(v bool) { - tag := uint8(bpTagBoolFalse) - if v { - tag = bpTagBoolTrue - } - binary.Write(p.writer, binary.BigEndian, tag) -} - -func (p *bplistGenerator) writeIntTag(signed bool, n uint64) { - var tag uint8 - var val interface{} - switch { - case n <= uint64(0xff): - val = uint8(n) - tag = bpTagInteger | 0x0 - case n <= uint64(0xffff): - val = uint16(n) - tag = bpTagInteger | 0x1 - case n <= uint64(0xffffffff): - val = uint32(n) - tag = bpTagInteger | 0x2 - case n > uint64(0x7fffffffffffffff) && !signed: - // 64-bit values are always *signed* in format 00. - // Any unsigned value that doesn't intersect with the signed - // range must be sign-extended and stored as a SInt128 - val = n - tag = bpTagInteger | 0x4 - default: - val = n - tag = bpTagInteger | 0x3 - } - - binary.Write(p.writer, binary.BigEndian, tag) - if tag&0xF == 0x4 { - // SInt128; in the absence of true 128-bit integers in Go, - // we'll just fake the top half. We only got here because - // we had an unsigned 64-bit int that didn't fit, - // so sign extend it with zeroes. - binary.Write(p.writer, binary.BigEndian, uint64(0)) - } - binary.Write(p.writer, binary.BigEndian, val) -} - -func (p *bplistGenerator) writeUIDTag(u UID) { - nbytes := bplistMinimumIntSize(uint64(u)) - tag := uint8(bpTagUID | (nbytes - 1)) - - binary.Write(p.writer, binary.BigEndian, tag) - p.writeSizedInt(uint64(u), nbytes) -} - -func (p *bplistGenerator) writeRealTag(n float64, bits int) { - var tag uint8 = bpTagReal | 0x3 - var val interface{} = n - if bits == 32 { - val = float32(n) - tag = bpTagReal | 0x2 - } - - binary.Write(p.writer, binary.BigEndian, tag) - binary.Write(p.writer, binary.BigEndian, val) -} - -func (p *bplistGenerator) writeDateTag(t time.Time) { - tag := uint8(bpTagDate) | 0x3 - val := float64(t.In(time.UTC).UnixNano()) / float64(time.Second) - val -= 978307200 // Adjust to Apple Epoch - - binary.Write(p.writer, binary.BigEndian, tag) - binary.Write(p.writer, binary.BigEndian, val) -} - -func (p *bplistGenerator) writeCountedTag(tag uint8, count uint64) { - marker := tag - if count >= 0xF { - marker |= 0xF - } else { - marker |= uint8(count) - } - - binary.Write(p.writer, binary.BigEndian, marker) - - if count >= 0xF { - p.writeIntTag(false, count) - } -} - -func (p *bplistGenerator) writeDataTag(data []byte) { - p.writeCountedTag(bpTagData, uint64(len(data))) - binary.Write(p.writer, binary.BigEndian, data) -} - -func (p *bplistGenerator) writeStringTag(str string) { - for _, r := range str { - if r > 0x7F { - utf16Runes := utf16.Encode([]rune(str)) - p.writeCountedTag(bpTagUTF16String, uint64(len(utf16Runes))) - binary.Write(p.writer, binary.BigEndian, utf16Runes) - return - } - } - - p.writeCountedTag(bpTagASCIIString, uint64(len(str))) - binary.Write(p.writer, binary.BigEndian, []byte(str)) -} - -func (p *bplistGenerator) writeDictionaryTag(dict *cfDictionary) { - // assumption: sorted already; flattenPlistValue did this. - cnt := len(dict.keys) - p.writeCountedTag(bpTagDictionary, uint64(cnt)) - vals := make([]uint64, cnt*2) - for i, k := range dict.keys { - // invariant: keys have already been "uniqued" (as PStrings) - keyIdx, ok := p.objmap[cfString(k).hash()] - if !ok { - panic(errors.New("failed to find key " + k + " in object map during serialization")) - } - vals[i] = keyIdx - } - - for i, v := range dict.values { - // invariant: values have already been "uniqued" - objIdx, ok := p.indexForPlistValue(v) - if !ok { - panic(errors.New("failed to find value in object map during serialization")) - } - vals[i+cnt] = objIdx - } - - for _, v := range vals { - p.writeSizedInt(v, int(p.trailer.ObjectRefSize)) - } -} - -func (p *bplistGenerator) writeArrayTag(arr []cfValue) { - p.writeCountedTag(bpTagArray, uint64(len(arr))) - for _, v := range arr { - objIdx, ok := p.indexForPlistValue(v) - if !ok { - panic(errors.New("failed to find value in object map during serialization")) - } - - p.writeSizedInt(objIdx, int(p.trailer.ObjectRefSize)) - } -} - -func (p *bplistGenerator) Indent(i string) { - // There's nothing to indent. -} - -func newBplistGenerator(w io.Writer) *bplistGenerator { - return &bplistGenerator{ - writer: &countedWriter{Writer: mustWriter{w}}, - } -} diff --git a/vendor/howett.net/plist/bplist_parser.go b/vendor/howett.net/plist/bplist_parser.go deleted file mode 100644 index 1825b570be..0000000000 --- a/vendor/howett.net/plist/bplist_parser.go +++ /dev/null @@ -1,353 +0,0 @@ -package plist - -import ( - "bytes" - "encoding/binary" - "errors" - "fmt" - "io" - "io/ioutil" - "math" - "runtime" - "time" - "unicode/utf16" -) - -const ( - signedHighBits = 0xFFFFFFFFFFFFFFFF -) - -type offset uint64 - -type bplistParser struct { - buffer []byte - - reader io.ReadSeeker - version int - objects []cfValue // object ID to object - trailer bplistTrailer - trailerOffset uint64 - - containerStack []offset // slice of object offsets; manipulated during container deserialization -} - -func (p *bplistParser) validateDocumentTrailer() { - if p.trailer.OffsetTableOffset >= p.trailerOffset { - panic(fmt.Errorf("offset table beyond beginning of trailer (0x%x, trailer@0x%x)", p.trailer.OffsetTableOffset, p.trailerOffset)) - } - - if p.trailer.OffsetTableOffset < 9 { - panic(fmt.Errorf("offset table begins inside header (0x%x)", p.trailer.OffsetTableOffset)) - } - - if p.trailerOffset > (p.trailer.NumObjects*uint64(p.trailer.OffsetIntSize))+p.trailer.OffsetTableOffset { - panic(errors.New("garbage between offset table and trailer")) - } - - if p.trailer.OffsetTableOffset+(uint64(p.trailer.OffsetIntSize)*p.trailer.NumObjects) > p.trailerOffset { - panic(errors.New("offset table isn't long enough to address every object")) - } - - maxObjectRef := uint64(1) << (8 * p.trailer.ObjectRefSize) - if p.trailer.NumObjects > maxObjectRef { - panic(fmt.Errorf("more objects (%v) than object ref size (%v bytes) can support", p.trailer.NumObjects, p.trailer.ObjectRefSize)) - } - - if p.trailer.OffsetIntSize < uint8(8) && (uint64(1)<<(8*p.trailer.OffsetIntSize)) <= p.trailer.OffsetTableOffset { - panic(errors.New("offset size isn't big enough to address entire file")) - } - - if p.trailer.TopObject >= p.trailer.NumObjects { - panic(fmt.Errorf("top object #%d is out of range (only %d exist)", p.trailer.TopObject, p.trailer.NumObjects)) - } -} - -func (p *bplistParser) parseDocument() (pval cfValue, parseError error) { - defer func() { - if r := recover(); r != nil { - if _, ok := r.(runtime.Error); ok { - panic(r) - } - - parseError = plistParseError{"binary", r.(error)} - } - }() - - p.buffer, _ = ioutil.ReadAll(p.reader) - - l := len(p.buffer) - if l < 40 { - panic(errors.New("not enough data")) - } - - if !bytes.Equal(p.buffer[0:6], []byte{'b', 'p', 'l', 'i', 's', 't'}) { - panic(errors.New("incomprehensible magic")) - } - - p.version = int(((p.buffer[6] - '0') * 10) + (p.buffer[7] - '0')) - - if p.version > 1 { - panic(fmt.Errorf("unexpected version %d", p.version)) - } - - p.trailerOffset = uint64(l - 32) - p.trailer = bplistTrailer{ - SortVersion: p.buffer[p.trailerOffset+5], - OffsetIntSize: p.buffer[p.trailerOffset+6], - ObjectRefSize: p.buffer[p.trailerOffset+7], - NumObjects: binary.BigEndian.Uint64(p.buffer[p.trailerOffset+8:]), - TopObject: binary.BigEndian.Uint64(p.buffer[p.trailerOffset+16:]), - OffsetTableOffset: binary.BigEndian.Uint64(p.buffer[p.trailerOffset+24:]), - } - - p.validateDocumentTrailer() - - // INVARIANTS: - // - Entire offset table is before trailer - // - Offset table begins after header - // - Offset table can address entire document - // - Object IDs are big enough to support the number of objects in this plist - // - Top object is in range - - p.objects = make([]cfValue, p.trailer.NumObjects) - - pval = p.objectAtIndex(p.trailer.TopObject) - return -} - -// parseSizedInteger returns a 128-bit integer as low64, high64 -func (p *bplistParser) parseSizedInteger(off offset, nbytes int) (lo uint64, hi uint64, newOffset offset) { - // Per comments in CoreFoundation, format version 00 requires that all - // 1, 2 or 4-byte integers be interpreted as unsigned. 8-byte integers are - // signed (always?) and therefore must be sign extended here. - // negative 1, 2, or 4-byte integers are always emitted as 64-bit. - switch nbytes { - case 1: - lo, hi = uint64(p.buffer[off]), 0 - case 2: - lo, hi = uint64(binary.BigEndian.Uint16(p.buffer[off:])), 0 - case 4: - lo, hi = uint64(binary.BigEndian.Uint32(p.buffer[off:])), 0 - case 8: - lo = binary.BigEndian.Uint64(p.buffer[off:]) - if p.buffer[off]&0x80 != 0 { - // sign extend if lo is signed - hi = signedHighBits - } - case 16: - lo, hi = binary.BigEndian.Uint64(p.buffer[off+8:]), binary.BigEndian.Uint64(p.buffer[off:]) - default: - panic(errors.New("illegal integer size")) - } - newOffset = off + offset(nbytes) - return -} - -func (p *bplistParser) parseObjectRefAtOffset(off offset) (uint64, offset) { - oid, _, next := p.parseSizedInteger(off, int(p.trailer.ObjectRefSize)) - return oid, next -} - -func (p *bplistParser) parseOffsetAtOffset(off offset) (offset, offset) { - parsedOffset, _, next := p.parseSizedInteger(off, int(p.trailer.OffsetIntSize)) - return offset(parsedOffset), next -} - -func (p *bplistParser) objectAtIndex(index uint64) cfValue { - if index >= p.trailer.NumObjects { - panic(fmt.Errorf("invalid object#%d (max %d)", index, p.trailer.NumObjects)) - } - - if pval := p.objects[index]; pval != nil { - return pval - } - - off, _ := p.parseOffsetAtOffset(offset(p.trailer.OffsetTableOffset + (index * uint64(p.trailer.OffsetIntSize)))) - if off > offset(p.trailer.OffsetTableOffset-1) { - panic(fmt.Errorf("object#%d starts beyond beginning of object table (0x%x, table@0x%x)", index, off, p.trailer.OffsetTableOffset)) - } - - pval := p.parseTagAtOffset(off) - p.objects[index] = pval - return pval - -} - -func (p *bplistParser) pushNestedObject(off offset) { - for _, v := range p.containerStack { - if v == off { - p.panicNestedObject(off) - } - } - p.containerStack = append(p.containerStack, off) -} - -func (p *bplistParser) panicNestedObject(off offset) { - ids := "" - for _, v := range p.containerStack { - ids += fmt.Sprintf("0x%x > ", v) - } - - // %s0x%d: ids above ends with " > " - panic(fmt.Errorf("self-referential collection@0x%x (%s0x%x) cannot be deserialized", off, ids, off)) -} - -func (p *bplistParser) popNestedObject() { - p.containerStack = p.containerStack[:len(p.containerStack)-1] -} - -func (p *bplistParser) parseTagAtOffset(off offset) cfValue { - tag := p.buffer[off] - - switch tag & 0xF0 { - case bpTagNull: - switch tag & 0x0F { - case bpTagBoolTrue, bpTagBoolFalse: - return cfBoolean(tag == bpTagBoolTrue) - } - case bpTagInteger: - lo, hi, _ := p.parseIntegerAtOffset(off) - return &cfNumber{ - signed: hi == signedHighBits, // a signed integer is stored as a 128-bit integer with the top 64 bits set - value: lo, - } - case bpTagReal: - nbytes := 1 << (tag & 0x0F) - switch nbytes { - case 4: - bits := binary.BigEndian.Uint32(p.buffer[off+1:]) - return &cfReal{wide: false, value: float64(math.Float32frombits(bits))} - case 8: - bits := binary.BigEndian.Uint64(p.buffer[off+1:]) - return &cfReal{wide: true, value: math.Float64frombits(bits)} - } - panic(errors.New("illegal float size")) - case bpTagDate: - bits := binary.BigEndian.Uint64(p.buffer[off+1:]) - val := math.Float64frombits(bits) - - // Apple Epoch is 20110101000000Z - // Adjust for UNIX Time - val += 978307200 - - sec, fsec := math.Modf(val) - time := time.Unix(int64(sec), int64(fsec*float64(time.Second))).In(time.UTC) - return cfDate(time) - case bpTagData: - data := p.parseDataAtOffset(off) - return cfData(data) - case bpTagASCIIString: - str := p.parseASCIIStringAtOffset(off) - return cfString(str) - case bpTagUTF16String: - str := p.parseUTF16StringAtOffset(off) - return cfString(str) - case bpTagUID: // Somehow different than int: low half is nbytes - 1 instead of log2(nbytes) - lo, _, _ := p.parseSizedInteger(off+1, int(tag&0xF)+1) - return cfUID(lo) - case bpTagDictionary: - return p.parseDictionaryAtOffset(off) - case bpTagArray: - return p.parseArrayAtOffset(off) - } - panic(fmt.Errorf("unexpected atom 0x%2.02x at offset 0x%x", tag, off)) -} - -func (p *bplistParser) parseIntegerAtOffset(off offset) (uint64, uint64, offset) { - tag := p.buffer[off] - return p.parseSizedInteger(off+1, 1<<(tag&0xF)) -} - -func (p *bplistParser) countForTagAtOffset(off offset) (uint64, offset) { - tag := p.buffer[off] - cnt := uint64(tag & 0x0F) - if cnt == 0xF { - cnt, _, off = p.parseIntegerAtOffset(off + 1) - return cnt, off - } - return cnt, off + 1 -} - -func (p *bplistParser) parseDataAtOffset(off offset) []byte { - len, start := p.countForTagAtOffset(off) - if start+offset(len) > offset(p.trailer.OffsetTableOffset) { - panic(fmt.Errorf("data@0x%x too long (%v bytes, max is %v)", off, len, p.trailer.OffsetTableOffset-uint64(start))) - } - return p.buffer[start : start+offset(len)] -} - -func (p *bplistParser) parseASCIIStringAtOffset(off offset) string { - len, start := p.countForTagAtOffset(off) - if start+offset(len) > offset(p.trailer.OffsetTableOffset) { - panic(fmt.Errorf("ascii string@0x%x too long (%v bytes, max is %v)", off, len, p.trailer.OffsetTableOffset-uint64(start))) - } - - return zeroCopy8BitString(p.buffer, int(start), int(len)) -} - -func (p *bplistParser) parseUTF16StringAtOffset(off offset) string { - len, start := p.countForTagAtOffset(off) - bytes := len * 2 - if start+offset(bytes) > offset(p.trailer.OffsetTableOffset) { - panic(fmt.Errorf("utf16 string@0x%x too long (%v bytes, max is %v)", off, bytes, p.trailer.OffsetTableOffset-uint64(start))) - } - - u16s := make([]uint16, len) - for i := offset(0); i < offset(len); i++ { - u16s[i] = binary.BigEndian.Uint16(p.buffer[start+(i*2):]) - } - runes := utf16.Decode(u16s) - return string(runes) -} - -func (p *bplistParser) parseObjectListAtOffset(off offset, count uint64) []cfValue { - if off+offset(count*uint64(p.trailer.ObjectRefSize)) > offset(p.trailer.OffsetTableOffset) { - panic(fmt.Errorf("list@0x%x length (%v) puts its end beyond the offset table at 0x%x", off, count, p.trailer.OffsetTableOffset)) - } - objects := make([]cfValue, count) - - next := off - var oid uint64 - for i := uint64(0); i < count; i++ { - oid, next = p.parseObjectRefAtOffset(next) - objects[i] = p.objectAtIndex(oid) - } - - return objects -} - -func (p *bplistParser) parseDictionaryAtOffset(off offset) *cfDictionary { - p.pushNestedObject(off) - defer p.popNestedObject() - - // a dictionary is an object list of [key key key val val val] - cnt, start := p.countForTagAtOffset(off) - objects := p.parseObjectListAtOffset(start, cnt*2) - - keys := make([]string, cnt) - for i := uint64(0); i < cnt; i++ { - if str, ok := objects[i].(cfString); ok { - keys[i] = string(str) - } else { - panic(fmt.Errorf("dictionary@0x%x contains non-string key at index %d", off, i)) - } - } - - return &cfDictionary{ - keys: keys, - values: objects[cnt:], - } -} - -func (p *bplistParser) parseArrayAtOffset(off offset) *cfArray { - p.pushNestedObject(off) - defer p.popNestedObject() - - // an array is just an object list - cnt, start := p.countForTagAtOffset(off) - return &cfArray{p.parseObjectListAtOffset(start, cnt)} -} - -func newBplistParser(r io.ReadSeeker) *bplistParser { - return &bplistParser{reader: r} -} diff --git a/vendor/howett.net/plist/decode.go b/vendor/howett.net/plist/decode.go deleted file mode 100644 index 4c64667715..0000000000 --- a/vendor/howett.net/plist/decode.go +++ /dev/null @@ -1,119 +0,0 @@ -package plist - -import ( - "bytes" - "io" - "reflect" - "runtime" -) - -type parser interface { - parseDocument() (cfValue, error) -} - -// A Decoder reads a property list from an input stream. -type Decoder struct { - // the format of the most-recently-decoded property list - Format int - - reader io.ReadSeeker - lax bool -} - -// Decode works like Unmarshal, except it reads the decoder stream to find property list elements. -// -// After Decoding, the Decoder's Format field will be set to one of the plist format constants. -func (p *Decoder) Decode(v interface{}) (err error) { - defer func() { - if r := recover(); r != nil { - if _, ok := r.(runtime.Error); ok { - panic(r) - } - err = r.(error) - } - }() - - header := make([]byte, 6) - p.reader.Read(header) - p.reader.Seek(0, 0) - - var parser parser - var pval cfValue - if bytes.Equal(header, []byte("bplist")) { - parser = newBplistParser(p.reader) - pval, err = parser.parseDocument() - if err != nil { - // Had a bplist header, but still got an error: we have to die here. - return err - } - p.Format = BinaryFormat - } else { - parser = newXMLPlistParser(p.reader) - pval, err = parser.parseDocument() - if _, ok := err.(invalidPlistError); ok { - // Rewind: the XML parser might have exhausted the file. - p.reader.Seek(0, 0) - // We don't use parser here because we want the textPlistParser type - tp := newTextPlistParser(p.reader) - pval, err = tp.parseDocument() - if err != nil { - return err - } - p.Format = tp.format - if p.Format == OpenStepFormat { - // OpenStep property lists can only store strings, - // so we have to turn on lax mode here for the unmarshal step later. - p.lax = true - } - } else { - if err != nil { - return err - } - p.Format = XMLFormat - } - } - - p.unmarshal(pval, reflect.ValueOf(v)) - return -} - -// NewDecoder returns a Decoder that reads property list elements from a stream reader, r. -// NewDecoder requires a Seekable stream for the purposes of file type detection. -func NewDecoder(r io.ReadSeeker) *Decoder { - return &Decoder{Format: InvalidFormat, reader: r, lax: false} -} - -// Unmarshal parses a property list document and stores the result in the value pointed to by v. -// -// Unmarshal uses the inverse of the type encodings that Marshal uses, allocating heap-borne types as necessary. -// -// When given a nil pointer, Unmarshal allocates a new value for it to point to. -// -// To decode property list values into an interface value, Unmarshal decodes the property list into the concrete value contained -// in the interface value. If the interface value is nil, Unmarshal stores one of the following in the interface value: -// -// string, bool, uint64, float64 -// plist.UID for "CoreFoundation Keyed Archiver UIDs" (convertible to uint64) -// []byte, for plist data -// []interface{}, for plist arrays -// map[string]interface{}, for plist dictionaries -// -// If a property list value is not appropriate for a given value type, Unmarshal aborts immediately and returns an error. -// -// As Go does not support 128-bit types, and we don't want to pretend we're giving the user integer types (as opposed to -// secretly passing them structs), Unmarshal will drop the high 64 bits of any 128-bit integers encoded in binary property lists. -// (This is important because CoreFoundation serializes some large 64-bit values as 128-bit values with an empty high half.) -// -// When Unmarshal encounters an OpenStep property list, it will enter a relaxed parsing mode: OpenStep property lists can only store -// plain old data as strings, so we will attempt to recover integer, floating-point, boolean and date values wherever they are necessary. -// (for example, if Unmarshal attempts to unmarshal an OpenStep property list into a time.Time, it will try to parse the string it -// receives as a time.) -// -// Unmarshal returns the detected property list format and an error, if any. -func Unmarshal(data []byte, v interface{}) (format int, err error) { - r := bytes.NewReader(data) - dec := NewDecoder(r) - err = dec.Decode(v) - format = dec.Format - return -} diff --git a/vendor/howett.net/plist/doc.go b/vendor/howett.net/plist/doc.go deleted file mode 100644 index 457e60b60b..0000000000 --- a/vendor/howett.net/plist/doc.go +++ /dev/null @@ -1,5 +0,0 @@ -// Package plist implements encoding and decoding of Apple's "property list" format. -// Property lists come in three sorts: plain text (GNUStep and OpenStep), XML and binary. -// plist supports all of them. -// The mapping between property list and Go objects is described in the documentation for the Marshal and Unmarshal functions. -package plist diff --git a/vendor/howett.net/plist/encode.go b/vendor/howett.net/plist/encode.go deleted file mode 100644 index f81309b583..0000000000 --- a/vendor/howett.net/plist/encode.go +++ /dev/null @@ -1,126 +0,0 @@ -package plist - -import ( - "bytes" - "errors" - "io" - "reflect" - "runtime" -) - -type generator interface { - generateDocument(cfValue) - Indent(string) -} - -// An Encoder writes a property list to an output stream. -type Encoder struct { - writer io.Writer - format int - - indent string -} - -// Encode writes the property list encoding of v to the stream. -func (p *Encoder) Encode(v interface{}) (err error) { - defer func() { - if r := recover(); r != nil { - if _, ok := r.(runtime.Error); ok { - panic(r) - } - err = r.(error) - } - }() - - pval := p.marshal(reflect.ValueOf(v)) - if pval == nil { - panic(errors.New("plist: no root element to encode")) - } - - var g generator - switch p.format { - case XMLFormat: - g = newXMLPlistGenerator(p.writer) - case BinaryFormat, AutomaticFormat: - g = newBplistGenerator(p.writer) - case OpenStepFormat, GNUStepFormat: - g = newTextPlistGenerator(p.writer, p.format) - } - g.Indent(p.indent) - g.generateDocument(pval) - return -} - -// Indent turns on pretty-printing for the XML and Text property list formats. -// Each element begins on a new line and is preceded by one or more copies of indent according to its nesting depth. -func (p *Encoder) Indent(indent string) { - p.indent = indent -} - -// NewEncoder returns an Encoder that writes an XML property list to w. -func NewEncoder(w io.Writer) *Encoder { - return NewEncoderForFormat(w, XMLFormat) -} - -// NewEncoderForFormat returns an Encoder that writes a property list to w in the specified format. -// Pass AutomaticFormat to allow the library to choose the best encoding (currently BinaryFormat). -func NewEncoderForFormat(w io.Writer, format int) *Encoder { - return &Encoder{ - writer: w, - format: format, - } -} - -// NewBinaryEncoder returns an Encoder that writes a binary property list to w. -func NewBinaryEncoder(w io.Writer) *Encoder { - return NewEncoderForFormat(w, BinaryFormat) -} - -// Marshal returns the property list encoding of v in the specified format. -// -// Pass AutomaticFormat to allow the library to choose the best encoding (currently BinaryFormat). -// -// Marshal traverses the value v recursively. -// Any nil values encountered, other than the root, will be silently discarded as -// the property list format bears no representation for nil values. -// -// Strings, integers of varying size, floats and booleans are encoded unchanged. -// Strings bearing non-ASCII runes will be encoded differently depending upon the property list format: -// UTF-8 for XML property lists and UTF-16 for binary property lists. -// -// Slice and Array values are encoded as property list arrays, except for -// []byte values, which are encoded as data. -// -// Map values encode as dictionaries. The map's key type must be string; there is no provision for encoding non-string dictionary keys. -// -// Struct values are encoded as dictionaries, with only exported fields being serialized. Struct field encoding may be influenced with the use of tags. -// The tag format is: -// -// `plist:"[,flags...]"` -// -// The following flags are supported: -// -// omitempty Only include the field if it is not set to the zero value for its type. -// -// If the key is "-", the field is ignored. -// -// Anonymous struct fields are encoded as if their exported fields were exposed via the outer struct. -// -// Pointer values encode as the value pointed to. -// -// Channel, complex and function values cannot be encoded. Any attempt to do so causes Marshal to return an error. -func Marshal(v interface{}, format int) ([]byte, error) { - return MarshalIndent(v, format, "") -} - -// MarshalIndent works like Marshal, but each property list element -// begins on a new line and is preceded by one or more copies of indent according to its nesting depth. -func MarshalIndent(v interface{}, format int, indent string) ([]byte, error) { - buf := &bytes.Buffer{} - enc := NewEncoderForFormat(buf, format) - enc.Indent(indent) - if err := enc.Encode(v); err != nil { - return nil, err - } - return buf.Bytes(), nil -} diff --git a/vendor/howett.net/plist/fuzz.go b/vendor/howett.net/plist/fuzz.go deleted file mode 100644 index 18a3b4b9e0..0000000000 --- a/vendor/howett.net/plist/fuzz.go +++ /dev/null @@ -1,17 +0,0 @@ -// +build gofuzz - -package plist - -import ( - "bytes" -) - -func Fuzz(data []byte) int { - buf := bytes.NewReader(data) - - var obj interface{} - if err := NewDecoder(buf).Decode(&obj); err != nil { - return 0 - } - return 1 -} diff --git a/vendor/howett.net/plist/marshal.go b/vendor/howett.net/plist/marshal.go deleted file mode 100644 index c461dfb547..0000000000 --- a/vendor/howett.net/plist/marshal.go +++ /dev/null @@ -1,186 +0,0 @@ -package plist - -import ( - "encoding" - "reflect" - "time" -) - -func isEmptyValue(v reflect.Value) bool { - switch v.Kind() { - case reflect.Array, reflect.Map, reflect.Slice, reflect.String: - return v.Len() == 0 - case reflect.Bool: - return !v.Bool() - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return v.Int() == 0 - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - return v.Uint() == 0 - case reflect.Float32, reflect.Float64: - return v.Float() == 0 - case reflect.Interface, reflect.Ptr: - return v.IsNil() - } - return false -} - -var ( - plistMarshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem() - textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem() - timeType = reflect.TypeOf((*time.Time)(nil)).Elem() -) - -func implementsInterface(val reflect.Value, interfaceType reflect.Type) (interface{}, bool) { - if val.CanInterface() && val.Type().Implements(interfaceType) { - return val.Interface(), true - } - - if val.CanAddr() { - pv := val.Addr() - if pv.CanInterface() && pv.Type().Implements(interfaceType) { - return pv.Interface(), true - } - } - return nil, false -} - -func (p *Encoder) marshalPlistInterface(marshalable Marshaler) cfValue { - value, err := marshalable.MarshalPlist() - if err != nil { - panic(err) - } - return p.marshal(reflect.ValueOf(value)) -} - -// marshalTextInterface marshals a TextMarshaler to a plist string. -func (p *Encoder) marshalTextInterface(marshalable encoding.TextMarshaler) cfValue { - s, err := marshalable.MarshalText() - if err != nil { - panic(err) - } - return cfString(s) -} - -// marshalStruct marshals a reflected struct value to a plist dictionary -func (p *Encoder) marshalStruct(typ reflect.Type, val reflect.Value) cfValue { - tinfo, _ := getTypeInfo(typ) - - dict := &cfDictionary{ - keys: make([]string, 0, len(tinfo.fields)), - values: make([]cfValue, 0, len(tinfo.fields)), - } - for _, finfo := range tinfo.fields { - value := finfo.value(val) - if !value.IsValid() || finfo.omitEmpty && isEmptyValue(value) { - continue - } - dict.keys = append(dict.keys, finfo.name) - dict.values = append(dict.values, p.marshal(value)) - } - - return dict -} - -func (p *Encoder) marshalTime(val reflect.Value) cfValue { - time := val.Interface().(time.Time) - return cfDate(time) -} - -func (p *Encoder) marshal(val reflect.Value) cfValue { - if !val.IsValid() { - return nil - } - - if receiver, can := implementsInterface(val, plistMarshalerType); can { - return p.marshalPlistInterface(receiver.(Marshaler)) - } - - // time.Time implements TextMarshaler, but we need to store it in RFC3339 - if val.Type() == timeType { - return p.marshalTime(val) - } - if val.Kind() == reflect.Ptr || (val.Kind() == reflect.Interface && val.NumMethod() == 0) { - ival := val.Elem() - if ival.IsValid() && ival.Type() == timeType { - return p.marshalTime(ival) - } - } - - // Check for text marshaler. - if receiver, can := implementsInterface(val, textMarshalerType); can { - return p.marshalTextInterface(receiver.(encoding.TextMarshaler)) - } - - // Descend into pointers or interfaces - if val.Kind() == reflect.Ptr || (val.Kind() == reflect.Interface && val.NumMethod() == 0) { - val = val.Elem() - } - - // We got this far and still may have an invalid anything or nil ptr/interface - if !val.IsValid() || ((val.Kind() == reflect.Ptr || val.Kind() == reflect.Interface) && val.IsNil()) { - return nil - } - - typ := val.Type() - - if typ == uidType { - return cfUID(val.Uint()) - } - - if val.Kind() == reflect.Struct { - return p.marshalStruct(typ, val) - } - - switch val.Kind() { - case reflect.String: - return cfString(val.String()) - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return &cfNumber{signed: true, value: uint64(val.Int())} - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - return &cfNumber{signed: false, value: val.Uint()} - case reflect.Float32: - return &cfReal{wide: false, value: val.Float()} - case reflect.Float64: - return &cfReal{wide: true, value: val.Float()} - case reflect.Bool: - return cfBoolean(val.Bool()) - case reflect.Slice, reflect.Array: - if typ.Elem().Kind() == reflect.Uint8 { - bytes := []byte(nil) - if val.CanAddr() { - bytes = val.Bytes() - } else { - bytes = make([]byte, val.Len()) - reflect.Copy(reflect.ValueOf(bytes), val) - } - return cfData(bytes) - } else { - values := make([]cfValue, val.Len()) - for i, length := 0, val.Len(); i < length; i++ { - if subpval := p.marshal(val.Index(i)); subpval != nil { - values[i] = subpval - } - } - return &cfArray{values} - } - case reflect.Map: - if typ.Key().Kind() != reflect.String { - panic(&unknownTypeError{typ}) - } - - l := val.Len() - dict := &cfDictionary{ - keys: make([]string, 0, l), - values: make([]cfValue, 0, l), - } - for _, keyv := range val.MapKeys() { - if subpval := p.marshal(val.MapIndex(keyv)); subpval != nil { - dict.keys = append(dict.keys, keyv.String()) - dict.values = append(dict.values, subpval) - } - } - return dict - default: - panic(&unknownTypeError{typ}) - } -} diff --git a/vendor/howett.net/plist/must.go b/vendor/howett.net/plist/must.go deleted file mode 100644 index 2c2523d973..0000000000 --- a/vendor/howett.net/plist/must.go +++ /dev/null @@ -1,50 +0,0 @@ -package plist - -import ( - "io" - "strconv" -) - -type mustWriter struct { - io.Writer -} - -func (w mustWriter) Write(p []byte) (int, error) { - n, err := w.Writer.Write(p) - if err != nil { - panic(err) - } - return n, nil -} - -func mustParseInt(str string, base, bits int) int64 { - i, err := strconv.ParseInt(str, base, bits) - if err != nil { - panic(err) - } - return i -} - -func mustParseUint(str string, base, bits int) uint64 { - i, err := strconv.ParseUint(str, base, bits) - if err != nil { - panic(err) - } - return i -} - -func mustParseFloat(str string, bits int) float64 { - i, err := strconv.ParseFloat(str, bits) - if err != nil { - panic(err) - } - return i -} - -func mustParseBool(str string) bool { - i, err := strconv.ParseBool(str) - if err != nil { - panic(err) - } - return i -} diff --git a/vendor/howett.net/plist/plist.go b/vendor/howett.net/plist/plist.go deleted file mode 100644 index a4078b23e3..0000000000 --- a/vendor/howett.net/plist/plist.go +++ /dev/null @@ -1,85 +0,0 @@ -package plist - -import ( - "reflect" -) - -// Property list format constants -const ( - // Used by Decoder to represent an invalid property list. - InvalidFormat int = 0 - - // Used to indicate total abandon with regards to Encoder's output format. - AutomaticFormat = 0 - - XMLFormat = 1 - BinaryFormat = 2 - OpenStepFormat = 3 - GNUStepFormat = 4 -) - -var FormatNames = map[int]string{ - InvalidFormat: "unknown/invalid", - XMLFormat: "XML", - BinaryFormat: "Binary", - OpenStepFormat: "OpenStep", - GNUStepFormat: "GNUStep", -} - -type unknownTypeError struct { - typ reflect.Type -} - -func (u *unknownTypeError) Error() string { - return "plist: can't marshal value of type " + u.typ.String() -} - -type invalidPlistError struct { - format string - err error -} - -func (e invalidPlistError) Error() string { - s := "plist: invalid " + e.format + " property list" - if e.err != nil { - s += ": " + e.err.Error() - } - return s -} - -type plistParseError struct { - format string - err error -} - -func (e plistParseError) Error() string { - s := "plist: error parsing " + e.format + " property list" - if e.err != nil { - s += ": " + e.err.Error() - } - return s -} - -// A UID represents a unique object identifier. UIDs are serialized in a manner distinct from -// that of integers. -// -// UIDs cannot be serialized in OpenStepFormat or GNUStepFormat property lists. -type UID uint64 - -// Marshaler is the interface implemented by types that can marshal themselves into valid -// property list objects. The returned value is marshaled in place of the original value -// implementing Marshaler -// -// If an error is returned by MarshalPlist, marshaling stops and the error is returned. -type Marshaler interface { - MarshalPlist() (interface{}, error) -} - -// Unmarshaler is the interface implemented by types that can unmarshal themselves from -// property list objects. The UnmarshalPlist method receives a function that may -// be called to unmarshal the original property list value into a field or variable. -// -// It is safe to call the unmarshal function more than once. -type Unmarshaler interface { - UnmarshalPlist(unmarshal func(interface{}) error) error -} diff --git a/vendor/howett.net/plist/plist_types.go b/vendor/howett.net/plist/plist_types.go deleted file mode 100644 index 954ef34e9d..0000000000 --- a/vendor/howett.net/plist/plist_types.go +++ /dev/null @@ -1,139 +0,0 @@ -package plist - -import ( - "hash/crc32" - "sort" - "time" -) - -type cfValue interface { - typeName() string - hash() interface{} -} - -type cfDictionary struct { - keys sort.StringSlice - values []cfValue -} - -func (*cfDictionary) typeName() string { - return "dictionary" -} - -func (p *cfDictionary) hash() interface{} { - return p -} - -func (p *cfDictionary) Len() int { - return len(p.keys) -} - -func (p *cfDictionary) Less(i, j int) bool { - return p.keys.Less(i, j) -} - -func (p *cfDictionary) Swap(i, j int) { - p.keys.Swap(i, j) - p.values[i], p.values[j] = p.values[j], p.values[i] -} - -func (p *cfDictionary) sort() { - sort.Sort(p) -} - -type cfArray struct { - values []cfValue -} - -func (*cfArray) typeName() string { - return "array" -} - -func (p *cfArray) hash() interface{} { - return p -} - -type cfString string - -func (cfString) typeName() string { - return "string" -} - -func (p cfString) hash() interface{} { - return string(p) -} - -type cfNumber struct { - signed bool - value uint64 -} - -func (*cfNumber) typeName() string { - return "integer" -} - -func (p *cfNumber) hash() interface{} { - if p.signed { - return int64(p.value) - } - return p.value -} - -type cfReal struct { - wide bool - value float64 -} - -func (cfReal) typeName() string { - return "real" -} - -func (p *cfReal) hash() interface{} { - if p.wide { - return p.value - } - return float32(p.value) -} - -type cfBoolean bool - -func (cfBoolean) typeName() string { - return "boolean" -} - -func (p cfBoolean) hash() interface{} { - return bool(p) -} - -type cfUID UID - -func (cfUID) typeName() string { - return "UID" -} - -func (p cfUID) hash() interface{} { - return p -} - -type cfData []byte - -func (cfData) typeName() string { - return "data" -} - -func (p cfData) hash() interface{} { - // Data are uniqued by their checksums. - // Todo: Look at calculating this only once and storing it somewhere; - // crc32 is fairly quick, however. - return crc32.ChecksumIEEE([]byte(p)) -} - -type cfDate time.Time - -func (cfDate) typeName() string { - return "date" -} - -func (p cfDate) hash() interface{} { - return time.Time(p) -} diff --git a/vendor/howett.net/plist/text_generator.go b/vendor/howett.net/plist/text_generator.go deleted file mode 100644 index 53078ba542..0000000000 --- a/vendor/howett.net/plist/text_generator.go +++ /dev/null @@ -1,226 +0,0 @@ -package plist - -import ( - "encoding/hex" - "io" - "strconv" - "time" -) - -type textPlistGenerator struct { - writer io.Writer - format int - - quotableTable *characterSet - - indent string - depth int - - dictKvDelimiter, dictEntryDelimiter, arrayDelimiter []byte -} - -var ( - textPlistTimeLayout = "2006-01-02 15:04:05 -0700" - padding = "0000" -) - -func (p *textPlistGenerator) generateDocument(pval cfValue) { - p.writePlistValue(pval) -} - -func (p *textPlistGenerator) plistQuotedString(str string) string { - if str == "" { - return `""` - } - s := "" - quot := false - for _, r := range str { - if r > 0xFF { - quot = true - s += `\U` - us := strconv.FormatInt(int64(r), 16) - s += padding[len(us):] - s += us - } else if r > 0x7F { - quot = true - s += `\` - us := strconv.FormatInt(int64(r), 8) - s += padding[1+len(us):] - s += us - } else { - c := uint8(r) - if p.quotableTable.ContainsByte(c) { - quot = true - } - - switch c { - case '\a': - s += `\a` - case '\b': - s += `\b` - case '\v': - s += `\v` - case '\f': - s += `\f` - case '\\': - s += `\\` - case '"': - s += `\"` - case '\t', '\r', '\n': - fallthrough - default: - s += string(c) - } - } - } - if quot { - s = `"` + s + `"` - } - return s -} - -func (p *textPlistGenerator) deltaIndent(depthDelta int) { - if depthDelta < 0 { - p.depth-- - } else if depthDelta > 0 { - p.depth++ - } -} - -func (p *textPlistGenerator) writeIndent() { - if len(p.indent) == 0 { - return - } - if len(p.indent) > 0 { - p.writer.Write([]byte("\n")) - for i := 0; i < p.depth; i++ { - io.WriteString(p.writer, p.indent) - } - } -} - -func (p *textPlistGenerator) writePlistValue(pval cfValue) { - if pval == nil { - return - } - - switch pval := pval.(type) { - case *cfDictionary: - pval.sort() - p.writer.Write([]byte(`{`)) - p.deltaIndent(1) - for i, k := range pval.keys { - p.writeIndent() - io.WriteString(p.writer, p.plistQuotedString(k)) - p.writer.Write(p.dictKvDelimiter) - p.writePlistValue(pval.values[i]) - p.writer.Write(p.dictEntryDelimiter) - } - p.deltaIndent(-1) - p.writeIndent() - p.writer.Write([]byte(`}`)) - case *cfArray: - p.writer.Write([]byte(`(`)) - p.deltaIndent(1) - for _, v := range pval.values { - p.writeIndent() - p.writePlistValue(v) - p.writer.Write(p.arrayDelimiter) - } - p.deltaIndent(-1) - p.writeIndent() - p.writer.Write([]byte(`)`)) - case cfString: - io.WriteString(p.writer, p.plistQuotedString(string(pval))) - case *cfNumber: - if p.format == GNUStepFormat { - p.writer.Write([]byte(`<*I`)) - } - if pval.signed { - io.WriteString(p.writer, strconv.FormatInt(int64(pval.value), 10)) - } else { - io.WriteString(p.writer, strconv.FormatUint(pval.value, 10)) - } - if p.format == GNUStepFormat { - p.writer.Write([]byte(`>`)) - } - case *cfReal: - if p.format == GNUStepFormat { - p.writer.Write([]byte(`<*R`)) - } - // GNUstep does not differentiate between 32/64-bit floats. - io.WriteString(p.writer, strconv.FormatFloat(pval.value, 'g', -1, 64)) - if p.format == GNUStepFormat { - p.writer.Write([]byte(`>`)) - } - case cfBoolean: - if p.format == GNUStepFormat { - if pval { - p.writer.Write([]byte(`<*BY>`)) - } else { - p.writer.Write([]byte(`<*BN>`)) - } - } else { - if pval { - p.writer.Write([]byte(`1`)) - } else { - p.writer.Write([]byte(`0`)) - } - } - case cfData: - var hexencoded [9]byte - var l int - var asc = 9 - hexencoded[8] = ' ' - - p.writer.Write([]byte(`<`)) - b := []byte(pval) - for i := 0; i < len(b); i += 4 { - l = i + 4 - if l >= len(b) { - l = len(b) - // We no longer need the space - or the rest of the buffer. - // (we used >= above to get this part without another conditional :P) - asc = (l - i) * 2 - } - // Fill the buffer (only up to 8 characters, to preserve the space we implicitly include - // at the end of every encode) - hex.Encode(hexencoded[:8], b[i:l]) - io.WriteString(p.writer, string(hexencoded[:asc])) - } - p.writer.Write([]byte(`>`)) - case cfDate: - if p.format == GNUStepFormat { - p.writer.Write([]byte(`<*D`)) - io.WriteString(p.writer, time.Time(pval).In(time.UTC).Format(textPlistTimeLayout)) - p.writer.Write([]byte(`>`)) - } else { - io.WriteString(p.writer, p.plistQuotedString(time.Time(pval).In(time.UTC).Format(textPlistTimeLayout))) - } - } -} - -func (p *textPlistGenerator) Indent(i string) { - p.indent = i - if i == "" { - p.dictKvDelimiter = []byte(`=`) - } else { - // For pretty-printing - p.dictKvDelimiter = []byte(` = `) - } -} - -func newTextPlistGenerator(w io.Writer, format int) *textPlistGenerator { - table := &osQuotable - if format == GNUStepFormat { - table = &gsQuotable - } - return &textPlistGenerator{ - writer: mustWriter{w}, - format: format, - quotableTable: table, - dictKvDelimiter: []byte(`=`), - arrayDelimiter: []byte(`,`), - dictEntryDelimiter: []byte(`;`), - } -} diff --git a/vendor/howett.net/plist/text_parser.go b/vendor/howett.net/plist/text_parser.go deleted file mode 100644 index 7e49d6f7db..0000000000 --- a/vendor/howett.net/plist/text_parser.go +++ /dev/null @@ -1,515 +0,0 @@ -package plist - -import ( - "encoding/binary" - "errors" - "fmt" - "io" - "io/ioutil" - "runtime" - "strings" - "time" - "unicode/utf16" - "unicode/utf8" -) - -type textPlistParser struct { - reader io.Reader - format int - - input string - start int - pos int - width int -} - -func convertU16(buffer []byte, bo binary.ByteOrder) (string, error) { - if len(buffer)%2 != 0 { - return "", errors.New("truncated utf16") - } - - tmp := make([]uint16, len(buffer)/2) - for i := 0; i < len(buffer); i += 2 { - tmp[i/2] = bo.Uint16(buffer[i : i+2]) - } - return string(utf16.Decode(tmp)), nil -} - -func guessEncodingAndConvert(buffer []byte) (string, error) { - if len(buffer) >= 3 && buffer[0] == 0xEF && buffer[1] == 0xBB && buffer[2] == 0xBF { - // UTF-8 BOM - return zeroCopy8BitString(buffer, 3, len(buffer)-3), nil - } else if len(buffer) >= 2 { - // UTF-16 guesses - - switch { - // stream is big-endian (BOM is FE FF or head is 00 XX) - case (buffer[0] == 0xFE && buffer[1] == 0xFF): - return convertU16(buffer[2:], binary.BigEndian) - case (buffer[0] == 0 && buffer[1] != 0): - return convertU16(buffer, binary.BigEndian) - - // stream is little-endian (BOM is FE FF or head is XX 00) - case (buffer[0] == 0xFF && buffer[1] == 0xFE): - return convertU16(buffer[2:], binary.LittleEndian) - case (buffer[0] != 0 && buffer[1] == 0): - return convertU16(buffer, binary.LittleEndian) - } - } - - // fallback: assume ASCII (not great!) - return zeroCopy8BitString(buffer, 0, len(buffer)), nil -} - -func (p *textPlistParser) parseDocument() (pval cfValue, parseError error) { - defer func() { - if r := recover(); r != nil { - if _, ok := r.(runtime.Error); ok { - panic(r) - } - // Wrap all non-invalid-plist errors. - parseError = plistParseError{"text", r.(error)} - } - }() - - buffer, err := ioutil.ReadAll(p.reader) - if err != nil { - panic(err) - } - - p.input, err = guessEncodingAndConvert(buffer) - if err != nil { - panic(err) - } - - val := p.parsePlistValue() - - p.skipWhitespaceAndComments() - if p.peek() != eof { - if _, ok := val.(cfString); !ok { - p.error("garbage after end of document") - } - - p.start = 0 - p.pos = 0 - val = p.parseDictionary(true) - } - - pval = val - - return -} - -const eof rune = -1 - -func (p *textPlistParser) error(e string, args ...interface{}) { - line := strings.Count(p.input[:p.pos], "\n") - char := p.pos - strings.LastIndex(p.input[:p.pos], "\n") - 1 - panic(fmt.Errorf("%s at line %d character %d", fmt.Sprintf(e, args...), line, char)) -} - -func (p *textPlistParser) next() rune { - if int(p.pos) >= len(p.input) { - p.width = 0 - return eof - } - r, w := utf8.DecodeRuneInString(p.input[p.pos:]) - p.width = w - p.pos += p.width - return r -} - -func (p *textPlistParser) backup() { - p.pos -= p.width -} - -func (p *textPlistParser) peek() rune { - r := p.next() - p.backup() - return r -} - -func (p *textPlistParser) emit() string { - s := p.input[p.start:p.pos] - p.start = p.pos - return s -} - -func (p *textPlistParser) ignore() { - p.start = p.pos -} - -func (p *textPlistParser) empty() bool { - return p.start == p.pos -} - -func (p *textPlistParser) scanUntil(ch rune) { - if x := strings.IndexRune(p.input[p.pos:], ch); x >= 0 { - p.pos += x - return - } - p.pos = len(p.input) -} - -func (p *textPlistParser) scanUntilAny(chs string) { - if x := strings.IndexAny(p.input[p.pos:], chs); x >= 0 { - p.pos += x - return - } - p.pos = len(p.input) -} - -func (p *textPlistParser) scanCharactersInSet(ch *characterSet) { - for ch.Contains(p.next()) { - } - p.backup() -} - -func (p *textPlistParser) scanCharactersNotInSet(ch *characterSet) { - var r rune - for { - r = p.next() - if r == eof || ch.Contains(r) { - break - } - } - p.backup() -} - -func (p *textPlistParser) skipWhitespaceAndComments() { - for { - p.scanCharactersInSet(&whitespace) - if strings.HasPrefix(p.input[p.pos:], "//") { - p.scanCharactersNotInSet(&newlineCharacterSet) - } else if strings.HasPrefix(p.input[p.pos:], "/*") { - if x := strings.Index(p.input[p.pos:], "*/"); x >= 0 { - p.pos += x + 2 // skip the */ as well - continue // consume more whitespace - } else { - p.error("unexpected eof in block comment") - } - } else { - break - } - } - p.ignore() -} - -func (p *textPlistParser) parseOctalDigits(max int) uint64 { - var val uint64 - - for i := 0; i < max; i++ { - r := p.next() - - if r >= '0' && r <= '7' { - val <<= 3 - val |= uint64((r - '0')) - } else { - p.backup() - break - } - } - return val -} - -func (p *textPlistParser) parseHexDigits(max int) uint64 { - var val uint64 - - for i := 0; i < max; i++ { - r := p.next() - - if r >= 'a' && r <= 'f' { - val <<= 4 - val |= 10 + uint64((r - 'a')) - } else if r >= 'A' && r <= 'F' { - val <<= 4 - val |= 10 + uint64((r - 'A')) - } else if r >= '0' && r <= '9' { - val <<= 4 - val |= uint64((r - '0')) - } else { - p.backup() - break - } - } - return val -} - -// the \ has already been consumed -func (p *textPlistParser) parseEscape() string { - var s string - switch p.next() { - case 'a': - s = "\a" - case 'b': - s = "\b" - case 'v': - s = "\v" - case 'f': - s = "\f" - case 't': - s = "\t" - case 'r': - s = "\r" - case 'n': - s = "\n" - case '\\': - s = `\` - case '"': - s = `"` - case 'x': - s = string(rune(p.parseHexDigits(2))) - case 'u', 'U': - s = string(rune(p.parseHexDigits(4))) - case '0', '1', '2', '3', '4', '5', '6', '7': - p.backup() // we've already consumed one of the digits - s = string(rune(p.parseOctalDigits(3))) - default: - p.backup() // everything else should be accepted - } - p.ignore() // skip the entire escape sequence - return s -} - -// the " has already been consumed -func (p *textPlistParser) parseQuotedString() cfString { - p.ignore() // ignore the " - - slowPath := false - s := "" - - for { - p.scanUntilAny(`"\`) - switch p.peek() { - case eof: - p.error("unexpected eof in quoted string") - case '"': - section := p.emit() - p.pos++ // skip " - if !slowPath { - return cfString(section) - } else { - s += section - return cfString(s) - } - case '\\': - slowPath = true - s += p.emit() - p.next() // consume \ - s += p.parseEscape() - } - } -} - -func (p *textPlistParser) parseUnquotedString() cfString { - p.scanCharactersNotInSet(&gsQuotable) - s := p.emit() - if s == "" { - p.error("invalid unquoted string (found an unquoted character that should be quoted?)") - } - - return cfString(s) -} - -// the { has already been consumed -func (p *textPlistParser) parseDictionary(ignoreEof bool) *cfDictionary { - //p.ignore() // ignore the { - var keypv cfValue - keys := make([]string, 0, 32) - values := make([]cfValue, 0, 32) -outer: - for { - p.skipWhitespaceAndComments() - - switch p.next() { - case eof: - if !ignoreEof { - p.error("unexpected eof in dictionary") - } - fallthrough - case '}': - break outer - case '"': - keypv = p.parseQuotedString() - default: - p.backup() - keypv = p.parseUnquotedString() - } - - // INVARIANT: key can't be nil; parseQuoted and parseUnquoted - // will panic out before they return nil. - - p.skipWhitespaceAndComments() - - var val cfValue - n := p.next() - if n == ';' { - val = keypv - } else if n == '=' { - // whitespace is consumed within - val = p.parsePlistValue() - - p.skipWhitespaceAndComments() - - if p.next() != ';' { - p.error("missing ; in dictionary") - } - } else { - p.error("missing = in dictionary") - } - - keys = append(keys, string(keypv.(cfString))) - values = append(values, val) - } - - return &cfDictionary{keys: keys, values: values} -} - -// the ( has already been consumed -func (p *textPlistParser) parseArray() *cfArray { - //p.ignore() // ignore the ( - values := make([]cfValue, 0, 32) -outer: - for { - p.skipWhitespaceAndComments() - - switch p.next() { - case eof: - p.error("unexpected eof in array") - case ')': - break outer // done here - case ',': - continue // restart; ,) is valid and we don't want to blow it - default: - p.backup() - } - - pval := p.parsePlistValue() // whitespace is consumed within - if str, ok := pval.(cfString); ok && string(str) == "" { - // Empty strings in arrays are apparently skipped? - // TODO: Figure out why this was implemented. - continue - } - values = append(values, pval) - } - return &cfArray{values} -} - -// the <* have already been consumed -func (p *textPlistParser) parseGNUStepValue() cfValue { - typ := p.next() - p.ignore() - p.scanUntil('>') - - if typ == eof || typ == '>' || p.empty() || p.peek() == eof { - p.error("invalid GNUStep extended value") - } - - v := p.emit() - p.next() // consume the > - - switch typ { - case 'I': - if v[0] == '-' { - n := mustParseInt(v, 10, 64) - return &cfNumber{signed: true, value: uint64(n)} - } else { - n := mustParseUint(v, 10, 64) - return &cfNumber{signed: false, value: n} - } - case 'R': - n := mustParseFloat(v, 64) - return &cfReal{wide: true, value: n} // TODO(DH) 32/64 - case 'B': - b := v[0] == 'Y' - return cfBoolean(b) - case 'D': - t, err := time.Parse(textPlistTimeLayout, v) - if err != nil { - p.error(err.Error()) - } - - return cfDate(t.In(time.UTC)) - } - p.error("invalid GNUStep type " + string(typ)) - return nil -} - -// The < has already been consumed -func (p *textPlistParser) parseHexData() cfData { - buf := make([]byte, 256) - i := 0 - c := 0 - - for { - r := p.next() - switch r { - case eof: - p.error("unexpected eof in data") - case '>': - if c&1 == 1 { - p.error("uneven number of hex digits in data") - } - p.ignore() - return cfData(buf[:i]) - case ' ', '\t', '\n', '\r', '\u2028', '\u2029': // more lax than apple here: skip spaces - continue - } - - buf[i] <<= 4 - if r >= 'a' && r <= 'f' { - buf[i] |= 10 + byte((r - 'a')) - } else if r >= 'A' && r <= 'F' { - buf[i] |= 10 + byte((r - 'A')) - } else if r >= '0' && r <= '9' { - buf[i] |= byte((r - '0')) - } else { - p.error("unexpected hex digit `%c'", r) - } - - c++ - if c&1 == 0 { - i++ - if i >= len(buf) { - realloc := make([]byte, len(buf)*2) - copy(realloc, buf) - buf = realloc - } - } - } -} - -func (p *textPlistParser) parsePlistValue() cfValue { - for { - p.skipWhitespaceAndComments() - - switch p.next() { - case eof: - return &cfDictionary{} - case '<': - if p.next() == '*' { - p.format = GNUStepFormat - return p.parseGNUStepValue() - } - - p.backup() - return p.parseHexData() - case '"': - return p.parseQuotedString() - case '{': - return p.parseDictionary(false) - case '(': - return p.parseArray() - default: - p.backup() - return p.parseUnquotedString() - } - } -} - -func newTextPlistParser(r io.Reader) *textPlistParser { - return &textPlistParser{ - reader: r, - format: OpenStepFormat, - } -} diff --git a/vendor/howett.net/plist/text_tables.go b/vendor/howett.net/plist/text_tables.go deleted file mode 100644 index 319c55c59b..0000000000 --- a/vendor/howett.net/plist/text_tables.go +++ /dev/null @@ -1,43 +0,0 @@ -package plist - -type characterSet [4]uint64 - -func (s *characterSet) Contains(ch rune) bool { - return ch >= 0 && ch <= 255 && s.ContainsByte(byte(ch)) -} - -func (s *characterSet) ContainsByte(ch byte) bool { - return (s[ch/64]&(1<<(ch%64)) > 0) -} - -// Bitmap of characters that must be inside a quoted string -// when written to an old-style property list -// Low bits represent lower characters, and each uint64 represents 64 characters. -var gsQuotable = characterSet{ - 0x78001385ffffffff, - 0xa800000138000000, - 0xffffffffffffffff, - 0xffffffffffffffff, -} - -// 7f instead of 3f in the top line: CFOldStylePlist.c says . is valid, but they quote it. -var osQuotable = characterSet{ - 0xf4007f6fffffffff, - 0xf8000001f8000001, - 0xffffffffffffffff, - 0xffffffffffffffff, -} - -var whitespace = characterSet{ - 0x0000000100003f00, - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, -} - -var newlineCharacterSet = characterSet{ - 0x0000000000002400, - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, -} diff --git a/vendor/howett.net/plist/typeinfo.go b/vendor/howett.net/plist/typeinfo.go deleted file mode 100644 index f0b920f8a8..0000000000 --- a/vendor/howett.net/plist/typeinfo.go +++ /dev/null @@ -1,170 +0,0 @@ -package plist - -import ( - "reflect" - "strings" - "sync" -) - -// typeInfo holds details for the plist representation of a type. -type typeInfo struct { - fields []fieldInfo -} - -// fieldInfo holds details for the plist representation of a single field. -type fieldInfo struct { - idx []int - name string - omitEmpty bool -} - -var tinfoMap = make(map[reflect.Type]*typeInfo) -var tinfoLock sync.RWMutex - -// getTypeInfo returns the typeInfo structure with details necessary -// for marshalling and unmarshalling typ. -func getTypeInfo(typ reflect.Type) (*typeInfo, error) { - tinfoLock.RLock() - tinfo, ok := tinfoMap[typ] - tinfoLock.RUnlock() - if ok { - return tinfo, nil - } - tinfo = &typeInfo{} - if typ.Kind() == reflect.Struct { - n := typ.NumField() - for i := 0; i < n; i++ { - f := typ.Field(i) - if f.PkgPath != "" || f.Tag.Get("plist") == "-" { - continue // Private field - } - - // For embedded structs, embed its fields. - if f.Anonymous { - t := f.Type - if t.Kind() == reflect.Ptr { - t = t.Elem() - } - if t.Kind() == reflect.Struct { - inner, err := getTypeInfo(t) - if err != nil { - return nil, err - } - for _, finfo := range inner.fields { - finfo.idx = append([]int{i}, finfo.idx...) - if err := addFieldInfo(typ, tinfo, &finfo); err != nil { - return nil, err - } - } - continue - } - } - - finfo, err := structFieldInfo(typ, &f) - if err != nil { - return nil, err - } - - // Add the field if it doesn't conflict with other fields. - if err := addFieldInfo(typ, tinfo, finfo); err != nil { - return nil, err - } - } - } - tinfoLock.Lock() - tinfoMap[typ] = tinfo - tinfoLock.Unlock() - return tinfo, nil -} - -// structFieldInfo builds and returns a fieldInfo for f. -func structFieldInfo(typ reflect.Type, f *reflect.StructField) (*fieldInfo, error) { - finfo := &fieldInfo{idx: f.Index} - - // Split the tag from the xml namespace if necessary. - tag := f.Tag.Get("plist") - - // Parse flags. - tokens := strings.Split(tag, ",") - tag = tokens[0] - if len(tokens) > 1 { - tag = tokens[0] - for _, flag := range tokens[1:] { - switch flag { - case "omitempty": - finfo.omitEmpty = true - } - } - } - - if tag == "" { - // If the name part of the tag is completely empty, - // use the field name - finfo.name = f.Name - return finfo, nil - } - - finfo.name = tag - return finfo, nil -} - -// addFieldInfo adds finfo to tinfo.fields if there are no -// conflicts, or if conflicts arise from previous fields that were -// obtained from deeper embedded structures than finfo. In the latter -// case, the conflicting entries are dropped. -// A conflict occurs when the path (parent + name) to a field is -// itself a prefix of another path, or when two paths match exactly. -// It is okay for field paths to share a common, shorter prefix. -func addFieldInfo(typ reflect.Type, tinfo *typeInfo, newf *fieldInfo) error { - var conflicts []int - // First, figure all conflicts. Most working code will have none. - for i := range tinfo.fields { - oldf := &tinfo.fields[i] - if newf.name == oldf.name { - conflicts = append(conflicts, i) - } - } - - // Without conflicts, add the new field and return. - if conflicts == nil { - tinfo.fields = append(tinfo.fields, *newf) - return nil - } - - // If any conflict is shallower, ignore the new field. - // This matches the Go field resolution on embedding. - for _, i := range conflicts { - if len(tinfo.fields[i].idx) < len(newf.idx) { - return nil - } - } - - // Otherwise, the new field is shallower, and thus takes precedence, - // so drop the conflicting fields from tinfo and append the new one. - for c := len(conflicts) - 1; c >= 0; c-- { - i := conflicts[c] - copy(tinfo.fields[i:], tinfo.fields[i+1:]) - tinfo.fields = tinfo.fields[:len(tinfo.fields)-1] - } - tinfo.fields = append(tinfo.fields, *newf) - return nil -} - -// value returns v's field value corresponding to finfo. -// It's equivalent to v.FieldByIndex(finfo.idx), but initializes -// and dereferences pointers as necessary. -func (finfo *fieldInfo) value(v reflect.Value) reflect.Value { - for i, x := range finfo.idx { - if i > 0 { - t := v.Type() - if t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Struct { - if v.IsNil() { - v.Set(reflect.New(v.Type().Elem())) - } - v = v.Elem() - } - } - v = v.Field(x) - } - return v -} diff --git a/vendor/howett.net/plist/unmarshal.go b/vendor/howett.net/plist/unmarshal.go deleted file mode 100644 index 06f5d6fc36..0000000000 --- a/vendor/howett.net/plist/unmarshal.go +++ /dev/null @@ -1,317 +0,0 @@ -package plist - -import ( - "encoding" - "fmt" - "reflect" - "runtime" - "time" -) - -type incompatibleDecodeTypeError struct { - dest reflect.Type - src string // type name (from cfValue) -} - -func (u *incompatibleDecodeTypeError) Error() string { - return fmt.Sprintf("plist: type mismatch: tried to decode plist type `%v' into value of type `%v'", u.src, u.dest) -} - -var ( - plistUnmarshalerType = reflect.TypeOf((*Unmarshaler)(nil)).Elem() - textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem() - uidType = reflect.TypeOf(UID(0)) -) - -func isEmptyInterface(v reflect.Value) bool { - return v.Kind() == reflect.Interface && v.NumMethod() == 0 -} - -func (p *Decoder) unmarshalPlistInterface(pval cfValue, unmarshalable Unmarshaler) { - err := unmarshalable.UnmarshalPlist(func(i interface{}) (err error) { - defer func() { - if r := recover(); r != nil { - if _, ok := r.(runtime.Error); ok { - panic(r) - } - err = r.(error) - } - }() - p.unmarshal(pval, reflect.ValueOf(i)) - return - }) - - if err != nil { - panic(err) - } -} - -func (p *Decoder) unmarshalTextInterface(pval cfString, unmarshalable encoding.TextUnmarshaler) { - err := unmarshalable.UnmarshalText([]byte(pval)) - if err != nil { - panic(err) - } -} - -func (p *Decoder) unmarshalTime(pval cfDate, val reflect.Value) { - val.Set(reflect.ValueOf(time.Time(pval))) -} - -func (p *Decoder) unmarshalLaxString(s string, val reflect.Value) { - switch val.Kind() { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - i := mustParseInt(s, 10, 64) - val.SetInt(i) - return - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - i := mustParseUint(s, 10, 64) - val.SetUint(i) - return - case reflect.Float32, reflect.Float64: - f := mustParseFloat(s, 64) - val.SetFloat(f) - return - case reflect.Bool: - b := mustParseBool(s) - val.SetBool(b) - return - case reflect.Struct: - if val.Type() == timeType { - t, err := time.Parse(textPlistTimeLayout, s) - if err != nil { - panic(err) - } - val.Set(reflect.ValueOf(t.In(time.UTC))) - return - } - fallthrough - default: - panic(&incompatibleDecodeTypeError{val.Type(), "string"}) - } -} - -func (p *Decoder) unmarshal(pval cfValue, val reflect.Value) { - if pval == nil { - return - } - - if val.Kind() == reflect.Ptr { - if val.IsNil() { - val.Set(reflect.New(val.Type().Elem())) - } - val = val.Elem() - } - - if isEmptyInterface(val) { - v := p.valueInterface(pval) - val.Set(reflect.ValueOf(v)) - return - } - - incompatibleTypeError := &incompatibleDecodeTypeError{val.Type(), pval.typeName()} - - // time.Time implements TextMarshaler, but we need to parse it as RFC3339 - if date, ok := pval.(cfDate); ok { - if val.Type() == timeType { - p.unmarshalTime(date, val) - return - } - panic(incompatibleTypeError) - } - - if receiver, can := implementsInterface(val, plistUnmarshalerType); can { - p.unmarshalPlistInterface(pval, receiver.(Unmarshaler)) - return - } - - if val.Type() != timeType { - if receiver, can := implementsInterface(val, textUnmarshalerType); can { - if str, ok := pval.(cfString); ok { - p.unmarshalTextInterface(str, receiver.(encoding.TextUnmarshaler)) - } else { - panic(incompatibleTypeError) - } - return - } - } - - typ := val.Type() - - switch pval := pval.(type) { - case cfString: - if val.Kind() == reflect.String { - val.SetString(string(pval)) - return - } - if p.lax { - p.unmarshalLaxString(string(pval), val) - return - } - - panic(incompatibleTypeError) - case *cfNumber: - switch val.Kind() { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - val.SetInt(int64(pval.value)) - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - val.SetUint(pval.value) - default: - panic(incompatibleTypeError) - } - case *cfReal: - if val.Kind() == reflect.Float32 || val.Kind() == reflect.Float64 { - // TODO: Consider warning on a downcast (storing a 64-bit value in a 32-bit reflect) - val.SetFloat(pval.value) - } else { - panic(incompatibleTypeError) - } - case cfBoolean: - if val.Kind() == reflect.Bool { - val.SetBool(bool(pval)) - } else { - panic(incompatibleTypeError) - } - case cfData: - if val.Kind() == reflect.Slice && typ.Elem().Kind() == reflect.Uint8 { - val.SetBytes([]byte(pval)) - } else { - panic(incompatibleTypeError) - } - case cfUID: - if val.Type() == uidType { - val.SetUint(uint64(pval)) - } else { - switch val.Kind() { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - val.SetInt(int64(pval)) - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - val.SetUint(uint64(pval)) - default: - panic(incompatibleTypeError) - } - } - case *cfArray: - p.unmarshalArray(pval, val) - case *cfDictionary: - p.unmarshalDictionary(pval, val) - } -} - -func (p *Decoder) unmarshalArray(a *cfArray, val reflect.Value) { - var n int - if val.Kind() == reflect.Slice { - // Slice of element values. - // Grow slice. - cnt := len(a.values) + val.Len() - if cnt >= val.Cap() { - ncap := 2 * cnt - if ncap < 4 { - ncap = 4 - } - new := reflect.MakeSlice(val.Type(), val.Len(), ncap) - reflect.Copy(new, val) - val.Set(new) - } - n = val.Len() - val.SetLen(cnt) - } else if val.Kind() == reflect.Array { - if len(a.values) > val.Cap() { - panic(fmt.Errorf("plist: attempted to unmarshal %d values into an array of size %d", len(a.values), val.Cap())) - } - } else { - panic(&incompatibleDecodeTypeError{val.Type(), a.typeName()}) - } - - // Recur to read element into slice. - for _, sval := range a.values { - p.unmarshal(sval, val.Index(n)) - n++ - } - return -} - -func (p *Decoder) unmarshalDictionary(dict *cfDictionary, val reflect.Value) { - typ := val.Type() - switch val.Kind() { - case reflect.Struct: - tinfo, err := getTypeInfo(typ) - if err != nil { - panic(err) - } - - entries := make(map[string]cfValue, len(dict.keys)) - for i, k := range dict.keys { - sval := dict.values[i] - entries[k] = sval - } - - for _, finfo := range tinfo.fields { - p.unmarshal(entries[finfo.name], finfo.value(val)) - } - case reflect.Map: - if val.IsNil() { - val.Set(reflect.MakeMap(typ)) - } - - for i, k := range dict.keys { - sval := dict.values[i] - - keyv := reflect.ValueOf(k).Convert(typ.Key()) - mapElem := reflect.New(typ.Elem()).Elem() - - p.unmarshal(sval, mapElem) - val.SetMapIndex(keyv, mapElem) - } - default: - panic(&incompatibleDecodeTypeError{typ, dict.typeName()}) - } -} - -/* *Interface is modelled after encoding/json */ -func (p *Decoder) valueInterface(pval cfValue) interface{} { - switch pval := pval.(type) { - case cfString: - return string(pval) - case *cfNumber: - if pval.signed { - return int64(pval.value) - } - return pval.value - case *cfReal: - if pval.wide { - return pval.value - } else { - return float32(pval.value) - } - case cfBoolean: - return bool(pval) - case *cfArray: - return p.arrayInterface(pval) - case *cfDictionary: - return p.dictionaryInterface(pval) - case cfData: - return []byte(pval) - case cfDate: - return time.Time(pval) - case cfUID: - return UID(pval) - } - return nil -} - -func (p *Decoder) arrayInterface(a *cfArray) []interface{} { - out := make([]interface{}, len(a.values)) - for i, subv := range a.values { - out[i] = p.valueInterface(subv) - } - return out -} - -func (p *Decoder) dictionaryInterface(dict *cfDictionary) map[string]interface{} { - out := make(map[string]interface{}) - for i, k := range dict.keys { - subv := dict.values[i] - out[k] = p.valueInterface(subv) - } - return out -} diff --git a/vendor/howett.net/plist/util.go b/vendor/howett.net/plist/util.go deleted file mode 100644 index d4e437a4fb..0000000000 --- a/vendor/howett.net/plist/util.go +++ /dev/null @@ -1,25 +0,0 @@ -package plist - -import "io" - -type countedWriter struct { - io.Writer - nbytes int -} - -func (w *countedWriter) Write(p []byte) (int, error) { - n, err := w.Writer.Write(p) - w.nbytes += n - return n, err -} - -func (w *countedWriter) BytesWritten() int { - return w.nbytes -} - -func unsignedGetBase(s string) (string, int) { - if len(s) > 1 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X') { - return s[2:], 16 - } - return s, 10 -} diff --git a/vendor/howett.net/plist/xml_generator.go b/vendor/howett.net/plist/xml_generator.go deleted file mode 100644 index 0b59ed7f28..0000000000 --- a/vendor/howett.net/plist/xml_generator.go +++ /dev/null @@ -1,185 +0,0 @@ -package plist - -import ( - "bufio" - "encoding/base64" - "encoding/xml" - "io" - "math" - "strconv" - "time" -) - -const ( - xmlHEADER string = `` + "\n" - xmlDOCTYPE = `` + "\n" - xmlArrayTag = "array" - xmlDataTag = "data" - xmlDateTag = "date" - xmlDictTag = "dict" - xmlFalseTag = "false" - xmlIntegerTag = "integer" - xmlKeyTag = "key" - xmlPlistTag = "plist" - xmlRealTag = "real" - xmlStringTag = "string" - xmlTrueTag = "true" - - // magic value used in the XML encoding of UIDs - // (stored as a dictionary mapping CF$UID->integer) - xmlCFUIDMagic = "CF$UID" -) - -func formatXMLFloat(f float64) string { - switch { - case math.IsInf(f, 1): - return "inf" - case math.IsInf(f, -1): - return "-inf" - case math.IsNaN(f): - return "nan" - } - return strconv.FormatFloat(f, 'g', -1, 64) -} - -type xmlPlistGenerator struct { - *bufio.Writer - - indent string - depth int - putNewline bool -} - -func (p *xmlPlistGenerator) generateDocument(root cfValue) { - p.WriteString(xmlHEADER) - p.WriteString(xmlDOCTYPE) - - p.openTag(`plist version="1.0"`) - p.writePlistValue(root) - p.closeTag(xmlPlistTag) - p.Flush() -} - -func (p *xmlPlistGenerator) openTag(n string) { - p.writeIndent(1) - p.WriteByte('<') - p.WriteString(n) - p.WriteByte('>') -} - -func (p *xmlPlistGenerator) closeTag(n string) { - p.writeIndent(-1) - p.WriteString("') -} - -func (p *xmlPlistGenerator) element(n string, v string) { - p.writeIndent(0) - if len(v) == 0 { - p.WriteByte('<') - p.WriteString(n) - p.WriteString("/>") - } else { - p.WriteByte('<') - p.WriteString(n) - p.WriteByte('>') - - err := xml.EscapeText(p.Writer, []byte(v)) - if err != nil { - panic(err) - } - - p.WriteString("') - } -} - -func (p *xmlPlistGenerator) writeDictionary(dict *cfDictionary) { - dict.sort() - p.openTag(xmlDictTag) - for i, k := range dict.keys { - p.element(xmlKeyTag, k) - p.writePlistValue(dict.values[i]) - } - p.closeTag(xmlDictTag) -} - -func (p *xmlPlistGenerator) writeArray(a *cfArray) { - p.openTag(xmlArrayTag) - for _, v := range a.values { - p.writePlistValue(v) - } - p.closeTag(xmlArrayTag) -} - -func (p *xmlPlistGenerator) writePlistValue(pval cfValue) { - if pval == nil { - return - } - - switch pval := pval.(type) { - case cfString: - p.element(xmlStringTag, string(pval)) - case *cfNumber: - if pval.signed { - p.element(xmlIntegerTag, strconv.FormatInt(int64(pval.value), 10)) - } else { - p.element(xmlIntegerTag, strconv.FormatUint(pval.value, 10)) - } - case *cfReal: - p.element(xmlRealTag, formatXMLFloat(pval.value)) - case cfBoolean: - if bool(pval) { - p.element(xmlTrueTag, "") - } else { - p.element(xmlFalseTag, "") - } - case cfData: - p.element(xmlDataTag, base64.StdEncoding.EncodeToString([]byte(pval))) - case cfDate: - p.element(xmlDateTag, time.Time(pval).In(time.UTC).Format(time.RFC3339)) - case *cfDictionary: - p.writeDictionary(pval) - case *cfArray: - p.writeArray(pval) - case cfUID: - p.openTag(xmlDictTag) - p.element(xmlKeyTag, xmlCFUIDMagic) - p.element(xmlIntegerTag, strconv.FormatUint(uint64(pval), 10)) - p.closeTag(xmlDictTag) - } -} - -func (p *xmlPlistGenerator) writeIndent(delta int) { - if len(p.indent) == 0 { - return - } - - if delta < 0 { - p.depth-- - } - - if p.putNewline { - // from encoding/xml/marshal.go; it seems to be intended - // to suppress the first newline. - p.WriteByte('\n') - } else { - p.putNewline = true - } - for i := 0; i < p.depth; i++ { - p.WriteString(p.indent) - } - if delta > 0 { - p.depth++ - } -} - -func (p *xmlPlistGenerator) Indent(i string) { - p.indent = i -} - -func newXMLPlistGenerator(w io.Writer) *xmlPlistGenerator { - return &xmlPlistGenerator{Writer: bufio.NewWriter(w)} -} diff --git a/vendor/howett.net/plist/xml_parser.go b/vendor/howett.net/plist/xml_parser.go deleted file mode 100644 index 8d8cfd19bd..0000000000 --- a/vendor/howett.net/plist/xml_parser.go +++ /dev/null @@ -1,216 +0,0 @@ -package plist - -import ( - "encoding/base64" - "encoding/xml" - "errors" - "fmt" - "io" - "runtime" - "strings" - "time" -) - -type xmlPlistParser struct { - reader io.Reader - xmlDecoder *xml.Decoder - whitespaceReplacer *strings.Replacer - ntags int -} - -func (p *xmlPlistParser) parseDocument() (pval cfValue, parseError error) { - defer func() { - if r := recover(); r != nil { - if _, ok := r.(runtime.Error); ok { - panic(r) - } - if _, ok := r.(invalidPlistError); ok { - parseError = r.(error) - } else { - // Wrap all non-invalid-plist errors. - parseError = plistParseError{"XML", r.(error)} - } - } - }() - for { - if token, err := p.xmlDecoder.Token(); err == nil { - if element, ok := token.(xml.StartElement); ok { - pval = p.parseXMLElement(element) - if p.ntags == 0 { - panic(invalidPlistError{"XML", errors.New("no elements encountered")}) - } - return - } - } else { - // The first XML parse turned out to be invalid: - // we do not have an XML property list. - panic(invalidPlistError{"XML", err}) - } - } -} - -func (p *xmlPlistParser) parseXMLElement(element xml.StartElement) cfValue { - var charData xml.CharData - switch element.Name.Local { - case "plist": - p.ntags++ - for { - token, err := p.xmlDecoder.Token() - if err != nil { - panic(err) - } - - if el, ok := token.(xml.EndElement); ok && el.Name.Local == "plist" { - break - } - - if el, ok := token.(xml.StartElement); ok { - return p.parseXMLElement(el) - } - } - return nil - case "string": - p.ntags++ - err := p.xmlDecoder.DecodeElement(&charData, &element) - if err != nil { - panic(err) - } - - return cfString(charData) - case "integer": - p.ntags++ - err := p.xmlDecoder.DecodeElement(&charData, &element) - if err != nil { - panic(err) - } - - s := string(charData) - if len(s) == 0 { - panic(errors.New("invalid empty ")) - } - - if s[0] == '-' { - s, base := unsignedGetBase(s[1:]) - n := mustParseInt("-"+s, base, 64) - return &cfNumber{signed: true, value: uint64(n)} - } else { - s, base := unsignedGetBase(s) - n := mustParseUint(s, base, 64) - return &cfNumber{signed: false, value: n} - } - case "real": - p.ntags++ - err := p.xmlDecoder.DecodeElement(&charData, &element) - if err != nil { - panic(err) - } - - n := mustParseFloat(string(charData), 64) - return &cfReal{wide: true, value: n} - case "true", "false": - p.ntags++ - p.xmlDecoder.Skip() - - b := element.Name.Local == "true" - return cfBoolean(b) - case "date": - p.ntags++ - err := p.xmlDecoder.DecodeElement(&charData, &element) - if err != nil { - panic(err) - } - - t, err := time.ParseInLocation(time.RFC3339, string(charData), time.UTC) - if err != nil { - panic(err) - } - - return cfDate(t) - case "data": - p.ntags++ - err := p.xmlDecoder.DecodeElement(&charData, &element) - if err != nil { - panic(err) - } - - str := p.whitespaceReplacer.Replace(string(charData)) - - l := base64.StdEncoding.DecodedLen(len(str)) - bytes := make([]uint8, l) - l, err = base64.StdEncoding.Decode(bytes, []byte(str)) - if err != nil { - panic(err) - } - - return cfData(bytes[:l]) - case "dict": - p.ntags++ - var key *string - keys := make([]string, 0, 32) - values := make([]cfValue, 0, 32) - for { - token, err := p.xmlDecoder.Token() - if err != nil { - panic(err) - } - - if el, ok := token.(xml.EndElement); ok && el.Name.Local == "dict" { - if key != nil { - panic(errors.New("missing value in dictionary")) - } - break - } - - if el, ok := token.(xml.StartElement); ok { - if el.Name.Local == "key" { - var k string - p.xmlDecoder.DecodeElement(&k, &el) - key = &k - } else { - if key == nil { - panic(errors.New("missing key in dictionary")) - } - keys = append(keys, *key) - values = append(values, p.parseXMLElement(el)) - key = nil - } - } - } - - if len(keys) == 1 && keys[0] == "CF$UID" && len(values) == 1 { - if integer, ok := values[0].(*cfNumber); ok { - return cfUID(integer.value) - } - } - - return &cfDictionary{keys: keys, values: values} - case "array": - p.ntags++ - values := make([]cfValue, 0, 10) - for { - token, err := p.xmlDecoder.Token() - if err != nil { - panic(err) - } - - if el, ok := token.(xml.EndElement); ok && el.Name.Local == "array" { - break - } - - if el, ok := token.(xml.StartElement); ok { - values = append(values, p.parseXMLElement(el)) - } - } - return &cfArray{values} - } - err := fmt.Errorf("encountered unknown element %s", element.Name.Local) - if p.ntags == 0 { - // If out first XML tag is invalid, it might be an openstep data element, ala or <0101> - panic(invalidPlistError{"XML", err}) - } - panic(err) -} - -func newXMLPlistParser(r io.Reader) *xmlPlistParser { - return &xmlPlistParser{r, xml.NewDecoder(r), strings.NewReplacer("\t", "", "\n", "", " ", "", "\r", ""), 0} -} diff --git a/vendor/howett.net/plist/zerocopy.go b/vendor/howett.net/plist/zerocopy.go deleted file mode 100644 index 999f401b7e..0000000000 --- a/vendor/howett.net/plist/zerocopy.go +++ /dev/null @@ -1,20 +0,0 @@ -// +build !appengine - -package plist - -import ( - "reflect" - "unsafe" -) - -func zeroCopy8BitString(buf []byte, off int, len int) string { - if len == 0 { - return "" - } - - var s string - hdr := (*reflect.StringHeader)(unsafe.Pointer(&s)) - hdr.Data = uintptr(unsafe.Pointer(&buf[off])) - hdr.Len = len - return s -} diff --git a/vendor/howett.net/plist/zerocopy_appengine.go b/vendor/howett.net/plist/zerocopy_appengine.go deleted file mode 100644 index dbd9a1acfd..0000000000 --- a/vendor/howett.net/plist/zerocopy_appengine.go +++ /dev/null @@ -1,7 +0,0 @@ -// +build appengine - -package plist - -func zeroCopy8BitString(buf []byte, off int, len int) string { - return string(buf[off : off+len]) -} diff --git a/vendor/modules.txt b/vendor/modules.txt index 0677e280da..a9872be9ce 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -65,9 +65,6 @@ github.com/getlantern/ops # github.com/getlantern/systray v1.1.0 ## explicit; go 1.13 github.com/getlantern/systray -# github.com/ghodss/yaml v1.0.0 -## explicit -github.com/ghodss/yaml # github.com/go-chi/chi v4.1.2+incompatible ## explicit github.com/go-chi/chi @@ -107,32 +104,6 @@ github.com/inconshreveable/mousetrap # github.com/james-barrow/golang-ipc v0.0.0-20210227130457-95e7cc81f5e2 ## explicit; go 1.15 github.com/james-barrow/golang-ipc -# github.com/jaypipes/ghw v0.8.0 -## explicit; go 1.12 -github.com/jaypipes/ghw -github.com/jaypipes/ghw/pkg/baseboard -github.com/jaypipes/ghw/pkg/bios -github.com/jaypipes/ghw/pkg/block -github.com/jaypipes/ghw/pkg/chassis -github.com/jaypipes/ghw/pkg/context -github.com/jaypipes/ghw/pkg/cpu -github.com/jaypipes/ghw/pkg/gpu -github.com/jaypipes/ghw/pkg/linuxdmi -github.com/jaypipes/ghw/pkg/linuxpath -github.com/jaypipes/ghw/pkg/marshal -github.com/jaypipes/ghw/pkg/memory -github.com/jaypipes/ghw/pkg/net -github.com/jaypipes/ghw/pkg/option -github.com/jaypipes/ghw/pkg/pci -github.com/jaypipes/ghw/pkg/pci/address -github.com/jaypipes/ghw/pkg/product -github.com/jaypipes/ghw/pkg/snapshot -github.com/jaypipes/ghw/pkg/topology -github.com/jaypipes/ghw/pkg/unitutil -github.com/jaypipes/ghw/pkg/util -# github.com/jaypipes/pcidb v0.6.0 -## explicit; go 1.11 -github.com/jaypipes/pcidb # github.com/json-iterator/go v1.1.12 ## explicit; go 1.12 github.com/json-iterator/go @@ -171,9 +142,6 @@ github.com/mholt/archiver/v3 # github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db ## explicit github.com/mitchellh/colorstring -# github.com/mitchellh/go-homedir v1.1.0 -## explicit -github.com/mitchellh/go-homedir # github.com/mmcloughlin/avo v0.0.0-20200523190732-4439b6b2c061 ## explicit; go 1.11 github.com/mmcloughlin/avo/attr @@ -394,15 +362,9 @@ golang.zx2c4.com/wireguard/tun/wintun golang.zx2c4.com/wireguard/tun/wintun/memmod # gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f ## explicit -# gopkg.in/yaml.v2 v2.4.0 -## explicit; go 1.15 -gopkg.in/yaml.v2 # gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b ## explicit gopkg.in/yaml.v3 -# howett.net/plist v0.0.0-20181124034731-591f970eefbb -## explicit -howett.net/plist # nhooyr.io/websocket v1.8.2 ## explicit; go 1.13 nhooyr.io/websocket