SEBA-902 mock testing of redfish importer;
Remove hardcoded addresses and replace with config file / cmdline;
Support hostnames in importer as alternative to ip addresses;
Treat response 204 as success
Change-Id: I17e8e585e388c501c02867ce952bbe1fa9b09668
diff --git a/Dockerfile b/Dockerfile
index 2f9188b..4f924ef 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -18,9 +18,6 @@
FROM golang:1.12 AS build-env
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
RUN /bin/true | cat
-RUN mkdir /app
-COPY . /app/
-WORKDIR /app
ENV GO111MODULE=on
ENV PROTOC_VERSION="3.7.0"
ENV PROTOC_SHA256SUM="a1b8ed22d6dc53c5b8680a6f1760a305b33ef471bece482e92728f00ba2a2969"
@@ -29,18 +26,20 @@
gcc=4:8.3.0-1 \
curl=7.64.0-4 \
unzip=6.0-23+deb10u1
-
+RUN go get -u "google.golang.org/grpc" \
+ && go get "github.com/golang/protobuf/proto" \
+ && go get -v "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway" \
+ && go get -v "github.com/golang/protobuf/protoc-gen-go"
+RUN mkdir /app
+COPY . /app/
+WORKDIR /app
RUN curl -L -o /tmp/protoc-${PROTOC_VERSION}-linux-x86_64.zip https://github.com/google/protobuf/releases/download/v${PROTOC_VERSION}/protoc-${PROTOC_VERSION}-linux-x86_64.zip
RUN mkdir /tmp/protoc3
RUN echo "$PROTOC_SHA256SUM /tmp/protoc-${PROTOC_VERSION}-linux-x86_64.zip" | sha256sum -c - \
&& unzip /tmp/protoc-${PROTOC_VERSION}-linux-x86_64.zip -d /tmp/protoc3 \
&& mv /tmp/protoc3/bin/* /usr/local/bin/ \
&& mv /tmp/protoc3/include/* /usr/local/include/
-RUN go get -u "google.golang.org/grpc" \
- && go get "github.com/golang/protobuf/proto" \
- && go get -v "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway" \
- && go get -v "github.com/golang/protobuf/protoc-gen-go" \
- && protoc -I proto -I"${GOPATH}/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis" --go_out=plugins=grpc:proto/ proto/*.proto
+RUN protoc -I proto -I"${GOPATH}/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis" --go_out=plugins=grpc:proto/ proto/*.proto
RUN GO111MODULE=on CGO_ENABLED=0 GOOS=linux go build -mod=vendor -o main .
FROM alpine:3.9.4
diff --git a/Makefile b/Makefile
index 9d06f64..d9c5e70 100644
--- a/Makefile
+++ b/Makefile
@@ -59,8 +59,15 @@
build: docker-build
+docker-build: docker-build-importer
+ make -C demo_test docker-build
+ make -C mock-redfish-server docker-build
-docker-build:
+docker-push: docker-push-importer
+ make -C demo_test docker-push
+ make -C mock-redfish-server docker-push
+
+docker-build-importer:
docker build $(DOCKER_BUILD_ARGS) \
-t ${DOCKER_IMAGENAME} \
--build-arg org_label_schema_version="${VERSION}" \
@@ -69,9 +76,11 @@
--build-arg org_label_schema_build_date="${DOCKER_LABEL_BUILD_DATE}" \
--build-arg org_opencord_vcs_commit_date="${DOCKER_LABEL_COMMIT_DATE}" \
-f Dockerfile .
-docker-push:
+
+docker-push-importer:
docker push ${DOCKER_IMAGENAME}
+
PATH:=$(GOPATH)/bin:$(PATH)
HADOLINT=$(shell PATH=$(GOPATH):$(PATH) which hadolint)
diff --git a/config.go b/config.go
new file mode 100644
index 0000000..642f42d
--- /dev/null
+++ b/config.go
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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.
+ */
+
+// Implements global configuration for redfish importer
+package main
+
+import (
+ "fmt"
+ flags "github.com/jessevdk/go-flags"
+ "gopkg.in/yaml.v2"
+ "io/ioutil"
+ "log"
+ "os"
+ "path"
+ "path/filepath"
+ "strings"
+)
+
+type OutputType uint8
+
+type GlobalConfigSpec struct {
+ Kafka string `yaml:"kafka"`
+ Local string `yaml:"local"`
+ LocalGrpc string `yaml:"localgrpc"`
+}
+
+var (
+ CharReplacer = strings.NewReplacer("\\t", "\t", "\\n", "\n")
+
+ GlobalConfig = GlobalConfigSpec{
+ Kafka: "cord-kafka.default.svc.cluster.local:9092",
+ Local: "0.0.0.0:8080",
+ LocalGrpc: "0.0.0.0:50051",
+ }
+
+ GlobalCommandOptions = make(map[string]map[string]string)
+
+ GlobalOptions struct {
+ Config string `short:"c" long:"config" env:"PROXYCONFIG" value-name:"FILE" default:"" description:"Location of proxy config file"`
+ Kafka string `short:"k" long:"kafka" default:"" value-name:"SERVER:PORT" description:"IP/Host and port of Kafka"`
+ Local string `short:"l" long:"local" default:"" value-name:"SERVER:PORT" description:"IP/Host and port to listen on for http"`
+ LocalGrpc string `short:"g" long:"localgrpc" default:"" value-name:"SERVER:PORT" description:"IP/Host and port to listen on for grpc"`
+ }
+
+ Debug = log.New(os.Stdout, "DEBUG: ", 0)
+ Info = log.New(os.Stdout, "INFO: ", 0)
+ Warn = log.New(os.Stderr, "WARN: ", 0)
+ Error = log.New(os.Stderr, "ERROR: ", 0)
+)
+
+func ParseCommandLine() {
+ parser := flags.NewNamedParser(path.Base(os.Args[0]),
+ flags.HelpFlag|flags.PassDoubleDash|flags.PassAfterNonOption)
+ _, err := parser.AddGroup("Global Options", "", &GlobalOptions)
+ if err != nil {
+ panic(err)
+ }
+
+ _, err = parser.ParseArgs(os.Args[1:])
+ if err != nil {
+ _, ok := err.(*flags.Error)
+ if ok {
+ real := err.(*flags.Error)
+ if real.Type == flags.ErrHelp {
+ os.Stdout.WriteString(err.Error() + "\n")
+ os.Exit(0)
+ }
+ }
+
+ fmt.Fprintf(os.Stderr, "%s: %s\n", os.Args[0], err.Error())
+
+ os.Exit(1)
+ }
+}
+
+func ProcessGlobalOptions() {
+ if len(GlobalOptions.Config) == 0 {
+ home, err := os.UserHomeDir()
+ if err != nil {
+ Warn.Printf("Unable to discover the user's home directory: %s", err)
+ home = "~"
+ }
+ GlobalOptions.Config = filepath.Join(home, ".redfish-importer", "config")
+ }
+
+ if info, err := os.Stat(GlobalOptions.Config); err == nil && !info.IsDir() {
+ configFile, err := ioutil.ReadFile(GlobalOptions.Config)
+ if err != nil {
+ Error.Fatalf("Unable to read the configuration file '%s': %s",
+ GlobalOptions.Config, err.Error())
+ }
+ if err = yaml.Unmarshal(configFile, &GlobalConfig); err != nil {
+ Error.Fatalf("Unable to parse the configuration file '%s': %s",
+ GlobalOptions.Config, err.Error())
+ }
+ }
+
+ if GlobalOptions.Kafka != "" {
+ GlobalConfig.Kafka = GlobalOptions.Kafka
+ }
+ if GlobalOptions.Local != "" {
+ GlobalConfig.Local = GlobalOptions.Local
+ }
+ if GlobalOptions.LocalGrpc != "" {
+ GlobalConfig.LocalGrpc = GlobalOptions.LocalGrpc
+ }
+}
+
+func ShowGlobalOptions() {
+ log.Printf("Configuration:")
+ log.Printf(" Kafka: %v", GlobalConfig.Kafka)
+ log.Printf(" Listen Address: %v", GlobalConfig.Local)
+ log.Printf(" Grpc Listen Address: %v", GlobalConfig.LocalGrpc)
+}
diff --git a/demo_test/Dockerfile b/demo_test/Dockerfile
new file mode 100644
index 0000000..efd6ce9
--- /dev/null
+++ b/demo_test/Dockerfile
@@ -0,0 +1,62 @@
+# copyright 2018-present Open Networking Foundation
+#
+# 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.
+
+FROM golang:1.12 AS build-env
+SHELL ["/bin/bash", "-o", "pipefail", "-c"]
+RUN /bin/true | cat
+RUN apt-get update && apt-get install --no-install-recommends -y --allow-downgrades \
+ git=1:2.20.1-2+deb10u1 \
+ gcc=4:8.3.0-1 \
+ curl=7.64.0-4 \
+ unzip=6.0-23+deb10u1
+# Install these prereqs now so they get built into a container layer and cached
+# TODO: Revisit once demo-test implements mod=vendor
+RUN go get -v google.golang.org/grpc \
+ && go get -v github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway \
+ && go get -v github.com/golang/protobuf/protoc-gen-go \
+ && go get github.com/sirupsen/logrus \
+ && go get github.com/Shopify/sarama
+# Install protoc, same steps as in main importer dockerfile
+ENV PROTOC_VERSION="3.7.0"
+ENV PROTOC_SHA256SUM="a1b8ed22d6dc53c5b8680a6f1760a305b33ef471bece482e92728f00ba2a2969"
+RUN curl -L -o /tmp/protoc-${PROTOC_VERSION}-linux-x86_64.zip https://github.com/google/protobuf/releases/download/v${PROTOC_VERSION}/protoc-${PROTOC_VERSION}-linux-x86_64.zip \
+ && mkdir /tmp/protoc3 \
+ && echo "$PROTOC_SHA256SUM /tmp/protoc-${PROTOC_VERSION}-linux-x86_64.zip" | sha256sum -c - \
+ && unzip /tmp/protoc-${PROTOC_VERSION}-linux-x86_64.zip -d /tmp/protoc3 \
+ && mv /tmp/protoc3/bin/* /usr/local/bin/ \
+ && mv /tmp/protoc3/include/* /usr/local/include/
+RUN mkdir /app
+COPY . /app/
+WORKDIR /app
+ENV GO111MODULE=on
+ENV PROTOC_VERSION="3.7.0"
+ENV PROTOC_SHA256SUM="a1b8ed22d6dc53c5b8680a6f1760a305b33ef471bece482e92728f00ba2a2969"
+
+WORKDIR /app/demo_test
+RUN make prereq
+RUN make proto/importer.pb.go
+# Note: "make demotest" produces an executable that throws "No such file" errors. Investigate.
+RUN GO111MODULE=on CGO_ENABLED=0 GOOS=linux go build -o demotest .
+
+# Also build the client, as having it inside the container may facilitate testing without
+# having to setup port forwardin
+WORKDIR /app/demo_test/functional_test
+RUN GO111MODULE=on CGO_ENABLED=0 GOOS=linux go build -o dm .
+
+FROM alpine:3.9.4
+WORKDIR /app/demo_test
+COPY --from=build-env /app/demo_test/demotest .
+COPY --from=build-env /app/demo_test/functional_test/dm .
+ENTRYPOINT ["./demotest"]
+
diff --git a/demo_test/Makefile b/demo_test/Makefile
index 4296147..4ceae91 100644
--- a/demo_test/Makefile
+++ b/demo_test/Makefile
@@ -12,6 +12,26 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+# Configure shell
+SHELL = bash -eu -o pipefail
+
+# Variables
+VERSION ?= $(shell cat ../VERSION)
+CONTAINER_NAME ?= redfish-importer-demotest
+
+## Docker related
+DOCKER_REGISTRY ?=
+DOCKER_REPOSITORY ?=
+DOCKER_BUILD_ARGS ?=
+DOCKER_TAG ?= ${VERSION}
+DOCKER_IMAGENAME := ${DOCKER_REGISTRY}${DOCKER_REPOSITORY}${CONTAINER_NAME}:${DOCKER_TAG}
+
+## Docker labels. Only set ref and commit date if committed
+DOCKER_LABEL_VCS_URL ?= $(shell git remote get-url $(shell git remote))
+DOCKER_LABEL_VCS_REF ?= $(shell git diff-index --quiet HEAD -- && git rev-parse HEAD || echo "unknown")
+DOCKER_LABEL_COMMIT_DATE ?= $(shell git diff-index --quiet HEAD -- && git show -s --format=%cd --date=iso-strict HEAD || echo "unknown" )
+DOCKER_LABEL_BUILD_DATE ?= $(shell date -u "+%Y-%m-%dT%H:%M:%SZ")
+
prereq:
go get -v google.golang.org/grpc
go get -v github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway
@@ -22,10 +42,22 @@
demotest: prereq proto/importer.pb.go
go build -i -v -o $@
-
proto/importer.pb.go: ../proto/importer.proto
mkdir -p proto
protoc --proto_path=../proto \
-I${GOPATH}/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \
--go_out=plugins=grpc:proto/ \
../proto/importer.proto
+
+docker-build:
+ docker build $(DOCKER_BUILD_ARGS) \
+ -t ${DOCKER_IMAGENAME} \
+ --build-arg org_label_schema_version="${VERSION}" \
+ --build-arg org_label_schema_vcs_url="${DOCKER_LABEL_VCS_URL}" \
+ --build-arg org_label_schema_vcs_ref="${DOCKER_LABEL_VCS_REF}" \
+ --build-arg org_label_schema_build_date="${DOCKER_LABEL_BUILD_DATE}" \
+ --build-arg org_opencord_vcs_commit_date="${DOCKER_LABEL_COMMIT_DATE}" \
+ -f Dockerfile ..
+
+docker-push:
+ docker push ${DOCKER_IMAGENAME}
diff --git a/demo_test/config.go b/demo_test/config.go
new file mode 100644
index 0000000..e8bd589
--- /dev/null
+++ b/demo_test/config.go
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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.
+ */
+
+// Implements global configuration for demotest
+package main
+
+import (
+ "fmt"
+ flags "github.com/jessevdk/go-flags"
+ "gopkg.in/yaml.v2"
+ "io/ioutil"
+ "log"
+ "os"
+ "path"
+ "path/filepath"
+ "strings"
+)
+
+type OutputType uint8
+
+type GlobalConfigSpec struct {
+ Kafka string `yaml:"kafka"`
+ Local string `yaml:"local"`
+ Importer string `yaml:"importer"`
+}
+
+var (
+ CharReplacer = strings.NewReplacer("\\t", "\t", "\\n", "\n")
+
+ GlobalConfig = GlobalConfigSpec{
+ Kafka: "kafka_ip.sh",
+ Local: ":9999",
+ Importer: "localhost:31085",
+ }
+
+ GlobalCommandOptions = make(map[string]map[string]string)
+
+ GlobalOptions struct {
+ Config string `short:"c" long:"config" env:"PROXYCONFIG" value-name:"FILE" default:"" description:"Location of proxy config file"`
+ Kafka string `short:"k" long:"kafka" default:"" value-name:"SERVER:PORT" description:"IP/Host and port of Kafka"`
+ Importer string `short:"i" long:"importer" default:"" value-name:"SERVER:PORT" description:"IP/Host and port of Importer"`
+ Local string `short:"l" long:"local" default:"" value-name:"SERVER:PORT" description:"IP/Host and port to listen on"`
+ }
+
+ Debug = log.New(os.Stdout, "DEBUG: ", 0)
+ Info = log.New(os.Stdout, "INFO: ", 0)
+ Warn = log.New(os.Stderr, "WARN: ", 0)
+ Error = log.New(os.Stderr, "ERROR: ", 0)
+)
+
+func ParseCommandLine() {
+ parser := flags.NewNamedParser(path.Base(os.Args[0]),
+ flags.HelpFlag|flags.PassDoubleDash|flags.PassAfterNonOption)
+ _, err := parser.AddGroup("Global Options", "", &GlobalOptions)
+ if err != nil {
+ panic(err)
+ }
+
+ _, err = parser.ParseArgs(os.Args[1:])
+ if err != nil {
+ _, ok := err.(*flags.Error)
+ if ok {
+ real := err.(*flags.Error)
+ if real.Type == flags.ErrHelp {
+ os.Stdout.WriteString(err.Error() + "\n")
+ os.Exit(0)
+ }
+ }
+
+ fmt.Fprintf(os.Stderr, "%s: %s\n", os.Args[0], err.Error())
+
+ os.Exit(1)
+ }
+}
+
+func ProcessGlobalOptions() {
+ if len(GlobalOptions.Config) == 0 {
+ home, err := os.UserHomeDir()
+ if err != nil {
+ Warn.Printf("Unable to discover the user's home directory: %s", err)
+ home = "~"
+ }
+ GlobalOptions.Config = filepath.Join(home, ".redfish-importer", "demotest-config")
+ }
+
+ if info, err := os.Stat(GlobalOptions.Config); err == nil && !info.IsDir() {
+ configFile, err := ioutil.ReadFile(GlobalOptions.Config)
+ if err != nil {
+ Error.Fatalf("Unable to read the configuration file '%s': %s",
+ GlobalOptions.Config, err.Error())
+ }
+ if err = yaml.Unmarshal(configFile, &GlobalConfig); err != nil {
+ Error.Fatalf("Unable to parse the configuration file '%s': %s",
+ GlobalOptions.Config, err.Error())
+ }
+ }
+
+ if GlobalOptions.Kafka != "" {
+ GlobalConfig.Kafka = GlobalOptions.Kafka
+ }
+ if GlobalOptions.Local != "" {
+ GlobalConfig.Local = GlobalOptions.Local
+ }
+ if GlobalOptions.Importer != "" {
+ GlobalConfig.Importer = GlobalOptions.Importer
+ }
+}
+
+func ShowGlobalOptions() {
+ log.Printf("Configuration:")
+ log.Printf(" Kafka: %v", GlobalConfig.Kafka)
+ log.Printf(" Listen Address: %v", GlobalConfig.Local)
+}
diff --git a/demo_test/functional_test/test_cli.go b/demo_test/functional_test/test_cli.go
index 3a1bc95..81cfe07 100644
--- a/demo_test/functional_test/test_cli.go
+++ b/demo_test/functional_test/test_cli.go
@@ -19,16 +19,32 @@
import "bufio"
import "os"
import "strings"
+import "log"
func main() {
+ if len(os.Args) <= 1 {
+ log.Printf("Syntax: ./dm <arguments>")
+ os.Exit(-1)
+ }
+
// connect to this socket
cmdstr := strings.Join(os.Args[1:], " ")
- conn, _ := net.Dial("tcp", "127.0.0.1:9999")
+ conn, err := net.Dial("tcp", "127.0.0.1:9999")
+ if err != nil {
+ log.Printf("Error opening connection: %v", err)
+ os.Exit(-1)
+ }
+
// send to socket
fmt.Fprintf(conn, cmdstr+"\n")
// listen for reply
- message, _ := bufio.NewReader(conn).ReadString(';')
+ message, err := bufio.NewReader(conn).ReadString(';')
+ if err != nil {
+ log.Printf("Error reading result: %v", err)
+ os.Exit(-1)
+ }
+
message = strings.TrimSuffix(message, ";")
fmt.Print(message)
}
diff --git a/demo_test/test.go b/demo_test/test.go
index 438ae74..8d929a0 100644
--- a/demo_test/test.go
+++ b/demo_test/test.go
@@ -41,7 +41,6 @@
"alert": "Alert",
"update": "Update"}
-var default_address string = "localhost:31085"
var importerTopic = "importer"
var DataConsumer sarama.Consumer
@@ -95,20 +94,24 @@
}
func kafkainit() {
- cmd := exec.Command("/bin/sh", "kafka_ip.sh")
var kafkaIP string
- var out bytes.Buffer
- cmd.Stdout = &out
- err := cmd.Run()
- if err != nil {
- logrus.Info(err)
- os.Exit(1)
+ if GlobalConfig.Kafka == "kafka_ip.sh" {
+ cmd := exec.Command("/bin/sh", "kafka_ip.sh")
+ var out bytes.Buffer
+ cmd.Stdout = &out
+ err := cmd.Run()
+ if err != nil {
+ logrus.Info(err)
+ os.Exit(1)
+ }
+ kafkaIP = out.String()
+ kafkaIP = strings.TrimSuffix(kafkaIP, "\n")
+ kafkaIP = kafkaIP + ":9092"
+ logrus.Infof("IP address of kafka-cord-0:%s", kafkaIP)
+ } else {
+ kafkaIP = GlobalConfig.Kafka
}
- kafkaIP = out.String()
- kafkaIP = strings.TrimSuffix(kafkaIP, "\n")
- kafkaIP = kafkaIP + ":9092"
- logrus.Infof("IP address of kafka-cord-0:%s", kafkaIP)
config := sarama.NewConfig()
config.Consumer.Return.Errors = true
master, err := sarama.NewConsumer([]string{kafkaIP}, config)
@@ -119,20 +122,25 @@
go topicListener(&importerTopic, master)
}
+
func main() {
+ ParseCommandLine()
+ ProcessGlobalOptions()
+ ShowGlobalOptions()
+
http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
logrus.Info("Launching server...")
logrus.Info("kafkaInit starting")
kafkainit()
- ln, err := net.Listen("tcp", ":9999")
+ ln, err := net.Listen("tcp", GlobalConfig.Local)
if err != nil {
fmt.Println("could not listen")
logrus.Fatalf("did not listen: %v", err)
}
defer ln.Close()
- conn, err = grpc.Dial(default_address, grpc.WithInsecure())
+ conn, err = grpc.Dial(GlobalConfig.Importer, grpc.WithInsecure())
if err != nil {
logrus.Fatalf("did not connect: %v", err)
}
diff --git a/event_subscriber.go b/event_subscriber.go
index a6740b4..160b599 100644
--- a/event_subscriber.go
+++ b/event_subscriber.go
@@ -19,6 +19,7 @@
"encoding/json"
"fmt"
logrus "github.com/sirupsen/logrus"
+ "io"
"io/ioutil"
"net/http"
"os"
@@ -52,11 +53,11 @@
return
}
- if resp.StatusCode != 201 {
+ if resp.StatusCode != 201 && resp.StatusCode != 204 {
result := make(map[string]interface{})
dec := json.NewDecoder(resp.Body)
- if err := dec.Decode(&result); err != nil {
- logrus.Errorf("ERROR while adding event subscription:%s " + err.Error())
+ if err := dec.Decode(&result); err != nil && err != io.EOF {
+ logrus.Errorf("ERROR while adding event subscription:%s ", err.Error())
return
}
logrus.Infof("Result Decode %s", result)
diff --git a/go.mod b/go.mod
index ec4b244..218ddb6 100644
--- a/go.mod
+++ b/go.mod
@@ -3,11 +3,13 @@
go 1.12
require (
- github.com/Shopify/sarama v1.25.0
- github.com/golang/protobuf v1.3.2
- github.com/grpc-ecosystem/grpc-gateway v1.12.2
- github.com/klauspost/cpuid v1.2.1 // indirect
- github.com/sirupsen/logrus v1.4.2
- golang.org/x/net v0.0.0-20191119073136-fc4aabc6c914
- google.golang.org/grpc v1.27.0
+ github.com/Shopify/sarama v1.26.1
+ github.com/golang/protobuf v1.3.5
+ github.com/grpc-ecosystem/grpc-gateway v1.14.3 // indirect
+ github.com/jessevdk/go-flags v1.4.0
+ github.com/sirupsen/logrus v1.5.0
+ github.com/stretchr/objx v0.1.1 // indirect
+ golang.org/x/net v0.0.0-20200202094626-16171245cfb2
+ google.golang.org/grpc v1.28.1
+ gopkg.in/yaml.v2 v2.2.8
)
diff --git a/go.sum b/go.sum
index ee9ae8b..6fdbf68 100644
--- a/go.sum
+++ b/go.sum
@@ -1,30 +1,35 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
-github.com/Shopify/sarama v1.24.1 h1:svn9vfN3R1Hz21WR2Gj0VW9ehaDGkiOS+VqlIcZOkMI=
-github.com/Shopify/sarama v1.24.1/go.mod h1:fGP8eQ6PugKEI0iUETYYtnP6d1pH/bdDMTel1X5ajsU=
github.com/Shopify/sarama v1.25.0 h1:ch1ywjRLjfJtU+EaiJ+l0rWffQ6TRpyYmW4DX7Cb2SU=
github.com/Shopify/sarama v1.25.0/go.mod h1:y/CFFTO9eaMTNriwu/Q+W4eioLqiDMGkA1W+gmdfj8w=
+github.com/Shopify/sarama v1.26.1 h1:3jnfWKD7gVwbB1KSy/lE0szA9duPuSFLViK0o/d3DgA=
+github.com/Shopify/sarama v1.26.1/go.mod h1:NbSGBSSndYaIhRcBtY9V0U7AyH+x71bG668AuWys/yU=
github.com/Shopify/toxiproxy v2.1.4+incompatible h1:TKdv8HiTLgE5wdJuEML90aBgNWsokNbMijUGhmcoBJc=
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
+github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/eapache/go-resiliency v1.1.0 h1:1NtRmCAqadE2FN4ZcN6g90TP3uk8cg9rn9eNK2197aU=
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
+github.com/eapache/go-resiliency v1.2.0 h1:v7g92e/KSN71Rq7vSThKaWIq68fL4YHvWyiUKorFR1Q=
+github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 h1:YEetp8/yCZMuEPMUDHG0CW/brkkEp8mzqk2+ODEitlw=
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc=
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
+github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=
github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
github.com/frankban/quicktest v1.4.1 h1:Wv2VwvNn73pAdFIVUQRXYDFp31lXKbqblIXo/Q5GPSg=
github.com/frankban/quicktest v1.4.1/go.mod h1:36zfPVQyHxymz4cH7wlDmVwDrJuljRB60qkgn7rorfQ=
+github.com/frankban/quicktest v1.7.2/go.mod h1:jaStnuzAqU1AJdCO0l53JDCJrVDKcS03DbaAcR7Ks/o=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
@@ -33,51 +38,70 @@
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I=
+github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
+github.com/golang/protobuf v1.3.5 h1:F768QJ1E9tib+q5Sc8MkdJi1RxLTbRcTf8LJV56aRls=
+github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
-github.com/grpc-ecosystem/grpc-gateway v1.12.1 h1:zCy2xE9ablevUOrUZc3Dl72Dt+ya2FNAvC2yLYMHzi4=
-github.com/grpc-ecosystem/grpc-gateway v1.12.1/go.mod h1:8XEsbTttt/W+VvjtQhLACqCisSPWTxCZ7sBRjU6iH9c=
-github.com/grpc-ecosystem/grpc-gateway v1.12.2/go.mod h1:8XEsbTttt/W+VvjtQhLACqCisSPWTxCZ7sBRjU6iH9c=
+github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/grpc-ecosystem/grpc-gateway v1.14.3 h1:OCJlWkOUoTnl0neNGlf4fUm3TmbEtguw7vR+nGtnDjY=
+github.com/grpc-ecosystem/grpc-gateway v1.14.3/go.mod h1:6CwZWGDSPRJidgKAtJVvND6soZe6fT7iteq8wDPdhb0=
github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE=
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
+github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE=
+github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/jcmturner/gofork v0.0.0-20190328161633-dc7c13fece03 h1:FUwcHNlEqkqLjLBdCp5PRlCFijNjvcYANOZXzCfXwCM=
github.com/jcmturner/gofork v0.0.0-20190328161633-dc7c13fece03/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o=
-github.com/klauspost/compress v1.8.2 h1:Bx0qjetmNjdFXASH02NSAREKpiaDwkO1DRZ3dV2KCcs=
-github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
+github.com/jcmturner/gofork v1.0.0 h1:J7uCkflzTEhUZ64xqKnkDxq3kzc96ajM1Gli5ktUem8=
+github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o=
+github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA=
+github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/klauspost/compress v1.9.7 h1:hYW1gP94JUmAhBtJ+LNz5My+gBobDxPR1iVuKug26aA=
github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
-github.com/klauspost/cpuid v1.2.1 h1:vJi+O/nMdFt0vqm8NZBI6wzALWdA2X+egi0ogNyrC/w=
-github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
+github.com/klauspost/compress v1.9.8 h1:VMAMUUOh+gaxKTMk+zqbjsSjsIcUcL/LF4o63i82QyA=
+github.com/klauspost/compress v1.9.8/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/pierrec/lz4 v2.2.6+incompatible h1:6aCX4/YZ9v8q69hTyiR7dNLnTA3fgtKHVVW5BCd5Znw=
github.com/pierrec/lz4 v2.2.6+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
+github.com/pierrec/lz4 v2.4.1+incompatible h1:mFe7ttWaflA46Mhqh+jUfjp2qTbPYxLB2/OyBppH9dg=
+github.com/pierrec/lz4 v2.4.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a h1:9ZKAASQSHhDYGoxY8uLVpewe1GDZ2vu2Tr/vTdVAkFQ=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
+github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563 h1:dY6ETXrvDG7Sa4vE8ZQG4yqWg6UnOcbqTAahkV813vQ=
+github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
+github.com/sirupsen/logrus v1.5.0 h1:1N5EYkVAPEywqZRJd7cwnRtCb6xJx7NH3T3WUTF980Q=
+github.com/sirupsen/logrus v1.5.0/go.mod h1:+F7Ogzej0PZc/94MaYx/nvG9jOFMD2osvC3s+Squfpo=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5 h1:bselrhR0Or1vomJZC8ZIjWtbDmn9OYFLX5Ik9alpJpE=
golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
+golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72 h1:+ELyKg6m8UBf0nPFSqD0mi7zUfwPyXo23HNjMnXPz7w=
+golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
@@ -90,6 +114,8 @@
golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191119073136-fc4aabc6c914 h1:MlY3mEfbnWGmUi4rtHOtNnnnN4UJRGSyLPx+DXA5Sq4=
golang.org/x/net v0.0.0-20191119073136-fc4aabc6c914/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200202094626-16171245cfb2 h1:CCH4IOTTfewWjGOlSp+zGcjutRKlBEZQ6wTn8ozI/nI=
+golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -97,14 +123,19 @@
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
+golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
@@ -115,13 +146,14 @@
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA=
-google.golang.org/grpc v1.25.1 h1:wdKvqQk7IttEw92GoRyKG2IDrUIpgpj6H6m81yfeMW0=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
-google.golang.org/grpc v1.26.0 h1:2dTRdpdFEEhJYQD8EMLB61nnrzSCTbG38PhqdhvOltg=
-google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.0 h1:rRYRFMVgRv6E0D70Skyfsr28tDXIuuPZyWGMPdMcnXg=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
+google.golang.org/grpc v1.28.1 h1:C1QC6KzgSiLyBabDi87BbjaGreoRgGUF5nOyvfrAZ1k=
+google.golang.org/grpc v1.28.1/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/jcmturner/aescts.v1 v1.0.1 h1:cVVZBK2b1zY26haWB4vbBiZrfFQnfbTVrE3xZq6hrEw=
gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo=
gopkg.in/jcmturner/dnsutils.v1 v1.0.1 h1:cIuC1OLRGZrld+16ZJvvZxVJeKPsvd5eUIvxfoN5hSM=
@@ -130,9 +162,14 @@
gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4=
gopkg.in/jcmturner/gokrb5.v7 v7.2.3 h1:hHMV/yKPwMnJhPuPx7pH2Uw/3Qyf+thJYlisUc44010=
gopkg.in/jcmturner/gokrb5.v7 v7.2.3/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM=
+gopkg.in/jcmturner/gokrb5.v7 v7.5.0 h1:a9tsXlIDD9SKxotJMK3niV7rPZAJeX2aD/0yg3qlIrg=
+gopkg.in/jcmturner/gokrb5.v7 v7.5.0/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM=
gopkg.in/jcmturner/rpc.v1 v1.1.0 h1:QHIUxTX1ISuAv9dD2wJ9HWQVuWDX/Zc0PfeC2tjc4rU=
gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.3 h1:fvjTMHxHEw/mxHbtzPi3JCcKXQRAnQTBRo6YCJSVHKI=
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
+gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
diff --git a/kubernetes/deploy-redfish-importer.yaml b/kubernetes/deploy-redfish-importer.yaml
new file mode 100755
index 0000000..edbc582
--- /dev/null
+++ b/kubernetes/deploy-redfish-importer.yaml
@@ -0,0 +1,181 @@
+# Copyright 2018-present Open Networking Foundation
+#
+# 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.
+
+---
+
+apiVersion: apps/v1beta2
+kind: Deployment
+metadata:
+ name: mock-olt-1
+ labels:
+ app: mock-olt-1
+ chart: mock-olt-1
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: mock-olt-1
+ template:
+ metadata:
+ labels:
+ app: mock-olt-1
+ spec:
+ containers:
+ - name: mock-olt-1
+ image: opencord/redfish-mockup-server:latest
+ imagePullPolicy: Always
+ ports:
+ - containerPort: 8001
+ name: mock-redfish
+
+---
+
+apiVersion: v1
+kind: Service
+metadata:
+ name: mock-olt-1
+spec:
+ ports:
+ - name: mock-redfish
+ port: 8401
+ targetPort: 8001
+ selector:
+ app: mock-olt-1
+
+---
+
+apiVersion: apps/v1beta2
+kind: Deployment
+metadata:
+ name: mock-olt-2
+ labels:
+ app: mock-olt-2
+ chart: mock-olt-2
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: mock-olt-2
+ template:
+ metadata:
+ labels:
+ app: mock-olt-2
+ spec:
+ containers:
+ - name: mock-olt-2
+ image: opencord/redfish-mockup-server:latest
+ imagePullPolicy: Always
+ ports:
+ - containerPort: 8001
+ name: mock-redfish
+
+---
+
+apiVersion: v1
+kind: Service
+metadata:
+ name: mock-olt-2
+spec:
+ ports:
+ - name: mock-redfish
+ port: 8402
+ targetPort: 8001
+ selector:
+ app: mock-olt-2
+
+---
+
+apiVersion: apps/v1beta2
+kind: Deployment
+metadata:
+ name: redfish-importer
+ labels:
+ app: redfish-importer
+ chart: redfish-importer
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: redfish-importer
+ template:
+ metadata:
+ labels:
+ app: redfish-importer
+ spec:
+ containers:
+ - name: redfish-importer
+ image: opencord/device-management:latest
+ imagePullPolicy: Always
+ ports:
+ - containerPort: 50051
+ name: importer
+ command: ["./main"]
+ args: ["--kafka", "voltha-kafka-0.voltha-kafka-headless.voltha:9092"]
+
+---
+
+apiVersion: v1
+kind: Service
+metadata:
+ name: redfish-importer
+spec:
+ ports:
+ - name: redfish-importer
+ port: 31085
+ targetPort: 50051
+ selector:
+ app: redfish-importer
+
+---
+
+apiVersion: apps/v1beta2
+kind: Deployment
+metadata:
+ name: redfish-demotest
+ labels:
+ app: redfish-demotest
+ chart: redfish-demotest
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: redfish-demotest
+ template:
+ metadata:
+ labels:
+ app: redfish-demotest
+ spec:
+ containers:
+ - name: redfish-demotest
+ image: opencord/redfish-importer-demotest:latest
+ imagePullPolicy: Always
+ ports:
+ - containerPort: 9999
+ name: demotest
+ command: ["./demotest"]
+ args: ["--kafka", "voltha-kafka-0.voltha-kafka-headless.voltha:9092", "--importer", "redfish-importer:31085"]
+
+---
+
+apiVersion: v1
+kind: Service
+metadata:
+ name: redfish-demotest
+spec:
+ ports:
+ - name: redfish-demotest
+ port: 9999
+ targetPort: 9999
+ selector:
+ app: redfish-demotest
diff --git a/kubernetes/run-demotest-port-forward.sh b/kubernetes/run-demotest-port-forward.sh
new file mode 100644
index 0000000..1bc5a8d
--- /dev/null
+++ b/kubernetes/run-demotest-port-forward.sh
@@ -0,0 +1,17 @@
+# Copyright 2018-present Open Networking Foundation
+#
+# 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.
+
+while [[ 1 ]]; do
+ kubectl port-forward --address 0.0.0.0 service/redfish-demotest 9999:9999
+done
diff --git a/kubernetes/start-demotest-port-forward.sh b/kubernetes/start-demotest-port-forward.sh
new file mode 100644
index 0000000..9b9b4df
--- /dev/null
+++ b/kubernetes/start-demotest-port-forward.sh
@@ -0,0 +1,15 @@
+# Copyright 2018-present Open Networking Foundation
+#
+# 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.
+
+nohup bash ./run-demotest-port-forward.sh > /tmp/demotest-port-forward.out 2> /tmp/demotest-port-forward.err &
diff --git a/main.go b/main.go
index 4ccce34..930fbd2 100644
--- a/main.go
+++ b/main.go
@@ -398,8 +398,7 @@
}
func (s *Server) startgrpcserver() {
logrus.Info("starting gRPC Server")
- grpcport := ":50051"
- listener, gserver, err := NewGrpcServer(grpcport)
+ listener, gserver, err := NewGrpcServer(GlobalConfig.LocalGrpc)
if err != nil {
logrus.Errorf("Failed to create gRPC server: %s ", err)
panic(err)
@@ -423,7 +422,7 @@
config := sarama.NewConfig()
config.Producer.RequiredAcks = sarama.WaitForAll
config.Producer.Retry.Max = 10
- producer, err := sarama.NewAsyncProducer([]string{"cord-kafka.default.svc.cluster.local:9092"}, config)
+ producer, err := sarama.NewAsyncProducer([]string{GlobalConfig.Kafka}, config)
if err != nil {
panic(err)
}
@@ -454,7 +453,7 @@
func (s *Server) runServer() {
logrus.Info("Starting HTTP Server")
http.HandleFunc("/", s.handle_events)
- err := http.ListenAndServeTLS(":8080", "https-server.crt", "https-server.key", nil)
+ err := http.ListenAndServeTLS(GlobalConfig.Local, "https-server.crt", "https-server.key", nil)
if err != nil {
panic(err)
}
@@ -475,9 +474,12 @@
splits := strings.Split(ip_address, ":")
ip, port := splits[0], splits[1]
if net.ParseIP(ip) == nil {
- logrus.Errorf("Invalid IP address %s", ip)
- msg = "Invalid IP address " + ip + "\n"
- return
+ // also check to see if it's a valid hostname
+ if _, err := net.LookupIP(ip); err != nil {
+ logrus.Errorf("Invalid IP address %s", ip)
+ msg = "Invalid IP address " + ip + "\n"
+ return
+ }
}
if _, err := strconv.Atoi(port); err != nil {
logrus.Errorf("Port # %s is not an integer", port)
@@ -590,6 +592,10 @@
func main() {
logrus.Info("Starting Device-management Container")
+ ParseCommandLine()
+ ProcessGlobalOptions()
+ ShowGlobalOptions()
+
http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
client := &http.Client{
Timeout: 10 * time.Second,
diff --git a/mock-redfish-server/Dockerfile b/mock-redfish-server/Dockerfile
new file mode 100644
index 0000000..40476df
--- /dev/null
+++ b/mock-redfish-server/Dockerfile
@@ -0,0 +1,33 @@
+# copyright 2018-present Open Networking Foundation
+#
+# 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.
+
+# To generate mockup, run this inside container:
+# cd /Redfish-Mockup-Creator && mkdir mockup && python ./redfishMockupCreate.py -v -r 10.90.0.114:8888 -A None -S -D /Redfish-Mockup-Creator/mockup && tar -czf olt-redfish-mockup.tar.gz mockup/redfish
+
+# Deployment example to deploy two mock OLTs:
+# docker run -d -p 127.0.0.1:8401:8001 opencord/redfish-mockup-server:latest
+# docker run -d -p 127.0.0.1:8402:8001 opencord/redfish-mockup-server:latest
+
+FROM python:3.5.9
+RUN git clone --depth=1 --branch 1.0.9 https://github.com/DMTF/Redfish-Mockup-Server.git
+RUN git clone --depth=1 --branch 1.0.5 https://github.com/DMTF/Redfish-Mockup-Creator.git
+
+WORKDIR /Redfish-Mockup-Server
+RUN pip install -r requirements.txt
+
+COPY mockup ./mockup
+
+RUN openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 365 -out certificate.pem -subj "/C=NL/ST=CA/L=Menlo/O=ONF/OU=Development/CN=redfish.mock.server"
+
+CMD python redfishMockupServer.py -H 0.0.0.0 -p 8001 -T -s --cert certificate.pem --key key.pem -D /Redfish-Mockup-Server/mockup
diff --git a/mock-redfish-server/Makefile b/mock-redfish-server/Makefile
new file mode 100644
index 0000000..0b5362e
--- /dev/null
+++ b/mock-redfish-server/Makefile
@@ -0,0 +1,46 @@
+# Copyright 2018-present Open Networking Foundation
+#
+# 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.
+
+# Configure shell
+SHELL = bash -eu -o pipefail
+
+# Variables
+VERSION ?= $(shell cat ../VERSION)
+CONTAINER_NAME ?= redfish-mockup-server
+
+## Docker related
+DOCKER_REGISTRY ?=
+DOCKER_REPOSITORY ?=
+DOCKER_BUILD_ARGS ?=
+DOCKER_TAG ?= ${VERSION}
+DOCKER_IMAGENAME := ${DOCKER_REGISTRY}${DOCKER_REPOSITORY}${CONTAINER_NAME}:${DOCKER_TAG}
+
+## Docker labels. Only set ref and commit date if committed
+DOCKER_LABEL_VCS_URL ?= $(shell git remote get-url $(shell git remote))
+DOCKER_LABEL_VCS_REF ?= $(shell git diff-index --quiet HEAD -- && git rev-parse HEAD || echo "unknown")
+DOCKER_LABEL_COMMIT_DATE ?= $(shell git diff-index --quiet HEAD -- && git show -s --format=%cd --date=iso-strict HEAD || echo "unknown" )
+DOCKER_LABEL_BUILD_DATE ?= $(shell date -u "+%Y-%m-%dT%H:%M:%SZ")
+
+docker-build:
+ docker build $(DOCKER_BUILD_ARGS) \
+ -t ${DOCKER_IMAGENAME} \
+ --build-arg org_label_schema_version="${VERSION}" \
+ --build-arg org_label_schema_vcs_url="${DOCKER_LABEL_VCS_URL}" \
+ --build-arg org_label_schema_vcs_ref="${DOCKER_LABEL_VCS_REF}" \
+ --build-arg org_label_schema_build_date="${DOCKER_LABEL_BUILD_DATE}" \
+ --build-arg org_opencord_vcs_commit_date="${DOCKER_LABEL_COMMIT_DATE}" \
+ -f Dockerfile .
+
+docker-push:
+ docker push ${DOCKER_IMAGENAME}
diff --git a/mock-redfish-server/README.md b/mock-redfish-server/README.md
new file mode 100644
index 0000000..f766f8c
--- /dev/null
+++ b/mock-redfish-server/README.md
@@ -0,0 +1,11 @@
+This is a mockup of an OLT Running Redfish.
+
+It may be started as follows:
+
+```bash
+docker build -t opendcord/redfish-mockup-server:latest -f Dockerfile.redfish_mockup_server .
+docker run -d -p 127.0.0.1:8401:8001 opencord/redfish-mockup-server:latest
+```
+
+The mockup was generated by running https://github.com/DMTF/Redfish-Mockup-Creator against
+a physical Edgecore OLT.
diff --git a/mock-redfish-server/mockup/redfish/index.json b/mock-redfish-server/mockup/redfish/index.json
new file mode 100644
index 0000000..83f4c51
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/index.json
@@ -0,0 +1,3 @@
+{
+ "v1": "/redfish/v1"
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/AccountService/Accounts/admin/index.json b/mock-redfish-server/mockup/redfish/v1/AccountService/Accounts/admin/index.json
new file mode 100644
index 0000000..9926e0b
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/AccountService/Accounts/admin/index.json
@@ -0,0 +1,18 @@
+{
+ "Locked": false,
+ "Name": "",
+ "Links": {
+ "Role": {
+ "@odata.id": "/redfish/v1/AccountService/Roles/1"
+ }
+ },
+ "UserName": "admin",
+ "Id": "admin",
+ "Description": null,
+ "Password": "redfish",
+ "Enabled": true,
+ "@odata.type": "#ManagerAccount.v1_0_0.ManagerAccount",
+ "@odata.context": "/redfish/v1/$metadata#ManagerAccount.ManagerAccount",
+ "@odata.id": "/redfish/v1/AccountService/Accounts/admin",
+ "RoleId": "Administrator"
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/AccountService/Accounts/index.json b/mock-redfish-server/mockup/redfish/v1/AccountService/Accounts/index.json
new file mode 100644
index 0000000..ba4dd37
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/AccountService/Accounts/index.json
@@ -0,0 +1,12 @@
+{
+ "@odata.type": "#ManagerAccountCollection.ManagerAccountCollection",
+ "Name": "Accounts Collection",
+ "@odata.context": "/redfish/v1/$metadata#AccountService.AccountService",
+ "Members": [
+ {
+ "@odata.id": "/redfish/v1/AccountService/Accounts/admin"
+ }
+ ],
+ "@odata.id": "/redfish/v1/AccountService/Accounts",
+ "Members@odata.count": 1
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/AccountService/Roles/1/index.json b/mock-redfish-server/mockup/redfish/v1/AccountService/Roles/1/index.json
new file mode 100644
index 0000000..17c1605
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/AccountService/Roles/1/index.json
@@ -0,0 +1,16 @@
+{
+ "IsPredefined": true,
+ "@odata.type": "#Role.v1_0_0.Role",
+ "Name": "",
+ "@odata.context": "/redfish/v1/$metadata#Role.Role",
+ "Id": "1",
+ "Description": null,
+ "@odata.id": "/redfish/v1/AccountService/Roles/1",
+ "AssignedPrivileges": [
+ "Login",
+ "ConfigureManager",
+ "ConfigureUsers",
+ "ConfigureSelf",
+ "ConfigureComponents"
+ ]
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/AccountService/Roles/2/index.json b/mock-redfish-server/mockup/redfish/v1/AccountService/Roles/2/index.json
new file mode 100644
index 0000000..1b507f8
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/AccountService/Roles/2/index.json
@@ -0,0 +1,14 @@
+{
+ "IsPredefined": true,
+ "@odata.type": "#Role.v1_0_0.Role",
+ "Name": "",
+ "@odata.context": "/redfish/v1/$metadata#Role.Role",
+ "Id": "2",
+ "Description": null,
+ "@odata.id": "/redfish/v1/AccountService/Roles/2",
+ "AssignedPrivileges": [
+ "Login",
+ "ConfigureSelf",
+ "ConfigureComponents"
+ ]
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/AccountService/Roles/3/index.json b/mock-redfish-server/mockup/redfish/v1/AccountService/Roles/3/index.json
new file mode 100644
index 0000000..dacd2c5
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/AccountService/Roles/3/index.json
@@ -0,0 +1,13 @@
+{
+ "IsPredefined": true,
+ "@odata.type": "#Role.v1_0_0.Role",
+ "Name": "",
+ "@odata.context": "/redfish/v1/$metadata#Role.Role",
+ "Id": "3",
+ "Description": null,
+ "@odata.id": "/redfish/v1/AccountService/Roles/3",
+ "AssignedPrivileges": [
+ "Login",
+ "ConfigureSelf"
+ ]
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/AccountService/Roles/index.json b/mock-redfish-server/mockup/redfish/v1/AccountService/Roles/index.json
new file mode 100644
index 0000000..61d5746
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/AccountService/Roles/index.json
@@ -0,0 +1,18 @@
+{
+ "@odata.type": "#RoleCollection.RoleCollection",
+ "Name": "Roles Collection",
+ "@odata.context": "/redfish/v1/$metadata#RoleCollection.RoleCollection",
+ "Members": [
+ {
+ "@odata.id": "/redfish/v1/AccountService/Roles/1"
+ },
+ {
+ "@odata.id": "/redfish/v1/AccountService/Roles/2"
+ },
+ {
+ "@odata.id": "/redfish/v1/AccountService/Roles/3"
+ }
+ ],
+ "@odata.id": "/redfish/v1/AccountService/Roles",
+ "Members@odata.count": 3
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/AccountService/index.json b/mock-redfish-server/mockup/redfish/v1/AccountService/index.json
new file mode 100644
index 0000000..f03bdc3
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/AccountService/index.json
@@ -0,0 +1,27 @@
+{
+ "MaxPasswordLength": 24,
+ "ServiceEnabled": true,
+ "Name": "Account Service",
+ "Roles": {
+ "@odata.id": "/redfish/v1/AccountService/Roles"
+ },
+ "Id": "AccountService",
+ "Description": "Account Service ",
+ "AuthFailureLoggingThreshold": 3,
+ "AccountLockoutCounterResetAfter": 30,
+ "MinPasswordLength": 6,
+ "Accounts": {
+ "@odata.id": "/redfish/v1/AccountService/Accounts"
+ },
+ "@odata.type": "#AccountService.v1_0_0.AccountService",
+ "AccountLockoutDuration": 30,
+ "@odata.context": "/redfish/v1/$metadata#AccountService.AccountService",
+ "Status": {
+ "State": "Enabled",
+ "HealthRollup": "OK",
+ "Health": "OK"
+ },
+ "AccountLockoutThreshold": 5,
+ "@odata.id": "/redfish/v1/AccountService",
+ "Oem": {}
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/Chassis/1/Drives/1/index.json b/mock-redfish-server/mockup/redfish/v1/Chassis/1/Drives/1/index.json
new file mode 100644
index 0000000..f9a3d96
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/Chassis/1/Drives/1/index.json
@@ -0,0 +1,58 @@
+{
+ "SerialNumber": "TS32ZBTMM1600_D486350097",
+ "Name": "Drive",
+ "IndicatorLED": null,
+ "Manufacturer": null,
+ "Actions": {
+ "#Drive.SecureErase": {
+ "target": "/redfish/v1/Chassis/1/Drives/1/Actions/Drive.SecureErase"
+ }
+ },
+ "EncryptionStatus": null,
+ "BlockSizeBytes": null,
+ "RotationSpeedRPM": null,
+ "@odata.id": "/redfish/v1/Chassis/1/Drives/1",
+ "MediaType": "SSD",
+ "StatusIndicator": null,
+ "Oem": {
+ "Intel_RackScale": {
+ "DriveErased": null,
+ "@odata.type": "#Intel.Oem.Drive",
+ "EraseOnDetach": null,
+ "Storage": {
+ "@odata.id": "/redfish/v1/Systems/1/Storage/1"
+ },
+ "FirmwareVersion": null,
+ "PCIeFunction": null
+ }
+ },
+ "AssetTag": null,
+ "EncryptionAbility": null,
+ "CapacityBytes": 32017047552,
+ "Links": {
+ "@odata.type": "#Drive.v1_1_0.Links",
+ "Endpoints": [],
+ "Volumes": []
+ },
+ "Id": "1",
+ "FailurePredicted": null,
+ "Description": "Drive description",
+ "HotspareType": null,
+ "Model": "",
+ "PredictedMediaLifeLeftPercent": null,
+ "Identifiers": [],
+ "Revision": "O0918B",
+ "NegotiatedSpeedGbs": null,
+ "Protocol": "SATA",
+ "@odata.type": "#Drive.v1_1_1.Drive",
+ "SKU": null,
+ "@odata.context": "/redfish/v1/$metadata#Chassis.Chassis",
+ "Status": {
+ "State": "Enabled",
+ "HealthRollup": "OK",
+ "Health": "OK"
+ },
+ "CapableSpeedGbs": null,
+ "Location": [],
+ "PartNumber": null
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/Chassis/1/Power/index.json b/mock-redfish-server/mockup/redfish/v1/Chassis/1/Power/index.json
new file mode 100644
index 0000000..80f43fe
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/Chassis/1/Power/index.json
@@ -0,0 +1,163 @@
+{
+ "@odata.type": "#Power.v1_1_0.Power",
+ "Name": "Power Collection",
+ "@odata.context": "/redfish/v1/$metadata#Power.Power",
+ "PowerSupplies": [
+ {
+ "SerialNumber": "TA020V581717000002",
+ "Name": "Power Supplies Unit",
+ "MemberId": "1",
+ "Status": {
+ "State": "Enabled",
+ "Health": "OK"
+ },
+ "FirmwareVersion": null,
+ "Manufacturer": null,
+ "Model": "YM-2651Y",
+ "RelatedItem": [
+ {
+ "@odata.id": "/redfish/v1/Chassis/1"
+ }
+ ],
+ "PowerCapacityWatts": null,
+ "@odata.id": "/redfish/v1/Chassis/1/Power",
+ "LineInputVoltage": null,
+ "SparePartNumber": null,
+ "LineInputVoltageType": null,
+ "LastPowerOutputWatts": 175,
+ "Oem": {},
+ "PartNumber": null,
+ "PowerSupplyType": "AC"
+ },
+ {
+ "SerialNumber": "NULL",
+ "Name": "Power Supplies Unit",
+ "MemberId": "2",
+ "Status": {
+ "State": "UnavailableOffline",
+ "Health": "OK"
+ },
+ "FirmwareVersion": null,
+ "Manufacturer": null,
+ "Model": "NULL",
+ "RelatedItem": [
+ {
+ "@odata.id": "/redfish/v1/Chassis/1"
+ }
+ ],
+ "PowerCapacityWatts": null,
+ "@odata.id": "/redfish/v1/Chassis/1/Power",
+ "LineInputVoltage": null,
+ "SparePartNumber": null,
+ "LineInputVoltageType": null,
+ "LastPowerOutputWatts": 0,
+ "Oem": {},
+ "PartNumber": null,
+ "PowerSupplyType": "Unknown"
+ }
+ ],
+ "Id": "Power",
+ "PowerControl": [
+ {
+ "Name": "System Power Control",
+ "MemberId": "1",
+ "PowerCapacityWatts": 0,
+ "PowerAvailableWatts": null,
+ "PowerLimit": {
+ "LimitException": null,
+ "CorrectionInMs": null,
+ "LimitInWatts": null
+ },
+ "RelatedItem": [
+ {
+ "@odata.id": "/redfish/v1/Chassis/1"
+ }
+ ],
+ "PowerConsumedWatts": 175,
+ "@odata.id": "/redfish/v1/Chassis/1/Power",
+ "Status": {
+ "State": "Enabled",
+ "Health": "OK"
+ },
+ "PowerRequestedWatts": null,
+ "PowerAllocatedWatts": null,
+ "Oem": {}
+ },
+ {
+ "Name": "System Power Control",
+ "MemberId": "2",
+ "PowerCapacityWatts": 0,
+ "PowerAvailableWatts": null,
+ "PowerLimit": {
+ "LimitException": null,
+ "CorrectionInMs": null,
+ "LimitInWatts": null
+ },
+ "RelatedItem": [
+ {
+ "@odata.id": "/redfish/v1/Chassis/1"
+ }
+ ],
+ "PowerConsumedWatts": 0,
+ "@odata.id": "/redfish/v1/Chassis/1/Power",
+ "Status": {
+ "State": "UnavailableOffline",
+ "Health": "OK"
+ },
+ "PowerRequestedWatts": null,
+ "PowerAllocatedWatts": null,
+ "Oem": {}
+ }
+ ],
+ "Description": "Collection of Power",
+ "@odata.id": "/redfish/v1/Chassis/1/Power",
+ "Oem": {},
+ "Voltages": [
+ {
+ "LowerThresholdFatal": null,
+ "Name": "Voltage",
+ "MemberId": "1",
+ "LowerThresholdCritical": null,
+ "PhysicalContext": "VoltageRegulator",
+ "RelatedItem": [
+ {
+ "@odata.id": "/redfish/v1/Chassis/1"
+ }
+ ],
+ "@odata.id": "/redfish/v1/Chassis/1/Power",
+ "LowerThresholdNonCritical": null,
+ "SensorNumber": 1,
+ "Status": {
+ "State": "Enabled",
+ "Health": "OK"
+ },
+ "UpperThresholdNonCritical": null,
+ "UpperThresholdFatal": null,
+ "UpperThresholdCritical": null,
+ "ReadingVolts": 11.89
+ },
+ {
+ "LowerThresholdFatal": null,
+ "Name": "Voltage",
+ "MemberId": "2",
+ "LowerThresholdCritical": null,
+ "PhysicalContext": "VoltageRegulator",
+ "RelatedItem": [
+ {
+ "@odata.id": "/redfish/v1/Chassis/1"
+ }
+ ],
+ "@odata.id": "/redfish/v1/Chassis/1/Power",
+ "LowerThresholdNonCritical": null,
+ "SensorNumber": 2,
+ "Status": {
+ "State": "Enabled",
+ "Health": "OK"
+ },
+ "UpperThresholdNonCritical": null,
+ "UpperThresholdFatal": null,
+ "UpperThresholdCritical": null,
+ "ReadingVolts": 0
+ }
+ ]
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/Chassis/1/Thermal/index.json b/mock-redfish-server/mockup/redfish/v1/Chassis/1/Thermal/index.json
new file mode 100644
index 0000000..91435c8
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/Chassis/1/Thermal/index.json
@@ -0,0 +1,373 @@
+{
+ "Temperatures": [
+ {
+ "LowerThresholdFatal": null,
+ "PhysicalContext": "CPU",
+ "MemberId": "1",
+ "ReadingCelsius": 52,
+ "LowerThresholdCritical": null,
+ "RelatedItem": [
+ {
+ "@odata.id": "/redfish/v1/Chassis/1"
+ }
+ ],
+ "Name": "System CPU Thermal Sensor Temperature",
+ "@odata.id": "/redfish/v1/Chassis/1/Thermal",
+ "LowerThresholdNonCritical": null,
+ "SensorNumber": 1,
+ "Status": {
+ "State": "Enabled",
+ "HealthRollup": null,
+ "Health": "OK"
+ },
+ "UpperThresholdNonCritical": 82,
+ "UpperThresholdFatal": 104,
+ "UpperThresholdCritical": 92
+ },
+ {
+ "LowerThresholdFatal": null,
+ "PhysicalContext": "SystemBoard",
+ "MemberId": "2",
+ "ReadingCelsius": 38.5,
+ "LowerThresholdCritical": null,
+ "RelatedItem": [
+ {
+ "@odata.id": "/redfish/v1/Chassis/1"
+ }
+ ],
+ "Name": "Chassis Thermal Sensor Temperature",
+ "@odata.id": "/redfish/v1/Chassis/1/Thermal",
+ "LowerThresholdNonCritical": null,
+ "SensorNumber": 2,
+ "Status": {
+ "State": "Enabled",
+ "HealthRollup": null,
+ "Health": "OK"
+ },
+ "UpperThresholdNonCritical": 45,
+ "UpperThresholdFatal": 60,
+ "UpperThresholdCritical": 55
+ },
+ {
+ "LowerThresholdFatal": null,
+ "PhysicalContext": "SystemBoard",
+ "MemberId": "3",
+ "ReadingCelsius": 32.5,
+ "LowerThresholdCritical": null,
+ "RelatedItem": [
+ {
+ "@odata.id": "/redfish/v1/Chassis/1"
+ }
+ ],
+ "Name": "Chassis Thermal Sensor Temperature",
+ "@odata.id": "/redfish/v1/Chassis/1/Thermal",
+ "LowerThresholdNonCritical": null,
+ "SensorNumber": 3,
+ "Status": {
+ "State": "Enabled",
+ "HealthRollup": null,
+ "Health": "OK"
+ },
+ "UpperThresholdNonCritical": 45,
+ "UpperThresholdFatal": 60,
+ "UpperThresholdCritical": 55
+ },
+ {
+ "LowerThresholdFatal": null,
+ "PhysicalContext": "SystemBoard",
+ "MemberId": "4",
+ "ReadingCelsius": 33,
+ "LowerThresholdCritical": null,
+ "RelatedItem": [
+ {
+ "@odata.id": "/redfish/v1/Chassis/1"
+ }
+ ],
+ "Name": "Chassis Thermal Sensor Temperature",
+ "@odata.id": "/redfish/v1/Chassis/1/Thermal",
+ "LowerThresholdNonCritical": null,
+ "SensorNumber": 4,
+ "Status": {
+ "State": "Enabled",
+ "HealthRollup": null,
+ "Health": "OK"
+ },
+ "UpperThresholdNonCritical": 45,
+ "UpperThresholdFatal": 60,
+ "UpperThresholdCritical": 55
+ },
+ {
+ "LowerThresholdFatal": null,
+ "PhysicalContext": "SystemBoard",
+ "MemberId": "5",
+ "ReadingCelsius": 37,
+ "LowerThresholdCritical": null,
+ "RelatedItem": [
+ {
+ "@odata.id": "/redfish/v1/Chassis/1"
+ }
+ ],
+ "Name": "Chassis Thermal Sensor Temperature",
+ "@odata.id": "/redfish/v1/Chassis/1/Thermal",
+ "LowerThresholdNonCritical": null,
+ "SensorNumber": 5,
+ "Status": {
+ "State": "Enabled",
+ "HealthRollup": null,
+ "Health": "OK"
+ },
+ "UpperThresholdNonCritical": 45,
+ "UpperThresholdFatal": 60,
+ "UpperThresholdCritical": 55
+ },
+ {
+ "LowerThresholdFatal": null,
+ "PhysicalContext": "PowerSupply",
+ "MemberId": "6",
+ "ReadingCelsius": 31,
+ "LowerThresholdCritical": null,
+ "RelatedItem": [
+ {
+ "@odata.id": "/redfish/v1/Chassis/1"
+ }
+ ],
+ "Name": "PSU Thermal Sensor Temperature",
+ "@odata.id": "/redfish/v1/Chassis/1/Thermal",
+ "LowerThresholdNonCritical": null,
+ "SensorNumber": 6,
+ "Status": {
+ "State": "Enabled",
+ "HealthRollup": null,
+ "Health": "OK"
+ },
+ "UpperThresholdNonCritical": 45,
+ "UpperThresholdFatal": 60,
+ "UpperThresholdCritical": 55
+ },
+ {
+ "LowerThresholdFatal": null,
+ "PhysicalContext": "PowerSupply",
+ "MemberId": "7",
+ "ReadingCelsius": 0,
+ "LowerThresholdCritical": null,
+ "RelatedItem": [
+ {
+ "@odata.id": "/redfish/v1/Chassis/1"
+ }
+ ],
+ "Name": "PSU Thermal Sensor Temperature",
+ "@odata.id": "/redfish/v1/Chassis/1/Thermal",
+ "LowerThresholdNonCritical": null,
+ "SensorNumber": 7,
+ "Status": {
+ "State": "Absent",
+ "HealthRollup": null,
+ "Health": "Warning"
+ },
+ "UpperThresholdNonCritical": 0,
+ "UpperThresholdFatal": 0,
+ "UpperThresholdCritical": 0
+ }
+ ],
+ "Redundancy": [],
+ "@odata.type": "#Thermal.v1_1_0.Thermal",
+ "Name": "Thermal",
+ "@odata.context": "/redfish/v1/$metadata#Thermal.Thermal",
+ "Id": "Thermal",
+ "Fans": [
+ {
+ "LowerThresholdFatal": null,
+ "PhysicalContext": "Back",
+ "MemberId": "1",
+ "LowerThresholdCritical": null,
+ "ReadingUnits": "RPM",
+ "RelatedItem": [
+ {
+ "@odata.id": "/redfish/v1/Chassis/1"
+ }
+ ],
+ "Name": "System Fan",
+ "@odata.id": "/redfish/v1/Chassis/1/Thermal",
+ "LowerThresholdNonCritical": null,
+ "Status": {
+ "State": "Enabled",
+ "HealthRollup": null,
+ "Health": "OK"
+ },
+ "Reading": 12700,
+ "UpperThresholdNonCritical": null,
+ "UpperThresholdFatal": null,
+ "UpperThresholdCritical": null
+ },
+ {
+ "LowerThresholdFatal": null,
+ "PhysicalContext": "Back",
+ "MemberId": "2",
+ "LowerThresholdCritical": null,
+ "ReadingUnits": "RPM",
+ "RelatedItem": [
+ {
+ "@odata.id": "/redfish/v1/Chassis/1"
+ }
+ ],
+ "Name": "System Fan",
+ "@odata.id": "/redfish/v1/Chassis/1/Thermal",
+ "LowerThresholdNonCritical": null,
+ "Status": {
+ "State": "Enabled",
+ "HealthRollup": null,
+ "Health": "OK"
+ },
+ "Reading": 12400,
+ "UpperThresholdNonCritical": null,
+ "UpperThresholdFatal": null,
+ "UpperThresholdCritical": null
+ },
+ {
+ "LowerThresholdFatal": null,
+ "PhysicalContext": "Back",
+ "MemberId": "3",
+ "LowerThresholdCritical": null,
+ "ReadingUnits": "RPM",
+ "RelatedItem": [
+ {
+ "@odata.id": "/redfish/v1/Chassis/1"
+ }
+ ],
+ "Name": "System Fan",
+ "@odata.id": "/redfish/v1/Chassis/1/Thermal",
+ "LowerThresholdNonCritical": null,
+ "Status": {
+ "State": "Enabled",
+ "HealthRollup": null,
+ "Health": "OK"
+ },
+ "Reading": 12700,
+ "UpperThresholdNonCritical": null,
+ "UpperThresholdFatal": null,
+ "UpperThresholdCritical": null
+ },
+ {
+ "LowerThresholdFatal": null,
+ "PhysicalContext": "Back",
+ "MemberId": "4",
+ "LowerThresholdCritical": null,
+ "ReadingUnits": "RPM",
+ "RelatedItem": [
+ {
+ "@odata.id": "/redfish/v1/Chassis/1"
+ }
+ ],
+ "Name": "System Fan",
+ "@odata.id": "/redfish/v1/Chassis/1/Thermal",
+ "LowerThresholdNonCritical": null,
+ "Status": {
+ "State": "Enabled",
+ "HealthRollup": null,
+ "Health": "OK"
+ },
+ "Reading": 12700,
+ "UpperThresholdNonCritical": null,
+ "UpperThresholdFatal": null,
+ "UpperThresholdCritical": null
+ },
+ {
+ "LowerThresholdFatal": null,
+ "PhysicalContext": "Back",
+ "MemberId": "5",
+ "LowerThresholdCritical": null,
+ "ReadingUnits": "RPM",
+ "RelatedItem": [
+ {
+ "@odata.id": "/redfish/v1/Chassis/1"
+ }
+ ],
+ "Name": "System Fan",
+ "@odata.id": "/redfish/v1/Chassis/1/Thermal",
+ "LowerThresholdNonCritical": null,
+ "Status": {
+ "State": "Enabled",
+ "HealthRollup": null,
+ "Health": "OK"
+ },
+ "Reading": 12600,
+ "UpperThresholdNonCritical": null,
+ "UpperThresholdFatal": null,
+ "UpperThresholdCritical": null
+ },
+ {
+ "LowerThresholdFatal": null,
+ "PhysicalContext": "Back",
+ "MemberId": "6",
+ "LowerThresholdCritical": null,
+ "ReadingUnits": "RPM",
+ "RelatedItem": [
+ {
+ "@odata.id": "/redfish/v1/Chassis/1"
+ }
+ ],
+ "Name": "System Fan",
+ "@odata.id": "/redfish/v1/Chassis/1/Thermal",
+ "LowerThresholdNonCritical": null,
+ "Status": {
+ "State": "Enabled",
+ "HealthRollup": null,
+ "Health": "OK"
+ },
+ "Reading": 12700,
+ "UpperThresholdNonCritical": null,
+ "UpperThresholdFatal": null,
+ "UpperThresholdCritical": null
+ },
+ {
+ "LowerThresholdFatal": null,
+ "PhysicalContext": "PowerSupply",
+ "MemberId": "7",
+ "LowerThresholdCritical": null,
+ "ReadingUnits": "RPM",
+ "RelatedItem": [
+ {
+ "@odata.id": "/redfish/v1/Chassis/1"
+ }
+ ],
+ "Name": "PSU Fan",
+ "@odata.id": "/redfish/v1/Chassis/1/Thermal",
+ "LowerThresholdNonCritical": null,
+ "Status": {
+ "State": "Enabled",
+ "HealthRollup": null,
+ "Health": "OK"
+ },
+ "Reading": 24480,
+ "UpperThresholdNonCritical": null,
+ "UpperThresholdFatal": null,
+ "UpperThresholdCritical": null
+ },
+ {
+ "LowerThresholdFatal": null,
+ "PhysicalContext": "PowerSupply",
+ "MemberId": "8",
+ "LowerThresholdCritical": null,
+ "ReadingUnits": "RPM",
+ "RelatedItem": [
+ {
+ "@odata.id": "/redfish/v1/Chassis/1"
+ }
+ ],
+ "Name": "PSU Fan",
+ "@odata.id": "/redfish/v1/Chassis/1/Thermal",
+ "LowerThresholdNonCritical": null,
+ "Status": {
+ "State": "Enabled",
+ "HealthRollup": null,
+ "Health": "Warning"
+ },
+ "Reading": 0,
+ "UpperThresholdNonCritical": null,
+ "UpperThresholdFatal": null,
+ "UpperThresholdCritical": null
+ }
+ ],
+ "Description": "Collection of Thermal sensors",
+ "@odata.id": "/redfish/v1/Chassis/1/Thermal"
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/Chassis/1/index.json b/mock-redfish-server/mockup/redfish/v1/Chassis/1/index.json
new file mode 100644
index 0000000..2311f64
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/Chassis/1/index.json
@@ -0,0 +1,85 @@
+{
+ "SerialNumber": "EC1721000216",
+ "Power": {
+ "@odata.id": "/redfish/v1/Chassis/1/Power"
+ },
+ "Name": "Chassis",
+ "Links": {
+ "@odata.type": "#Chassis.v1_2_0.Links",
+ "Storage": [
+ {
+ "@odata.id": "/redfish/v1/Systems/1/Storage/1"
+ }
+ ],
+ "ComputerSystems": [
+ {
+ "@odata.id": "/redfish/v1/Systems/1"
+ }
+ ],
+ "ManagedBy": [
+ {
+ "@odata.id": "/redfish/v1/Managers/1"
+ }
+ ],
+ "Oem": {
+ "Intel_RackScale": {
+ "Switches": [
+ {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1"
+ }
+ ],
+ "@odata.type": "#Intel.Oem.ChassisLinks"
+ }
+ },
+ "Contains": [],
+ "Drives": [
+ {
+ "@odata.id": "/redfish/v1/Chassis/1/Drives/1"
+ }
+ ]
+ },
+ "Id": "1",
+ "IndicatorLED": "Lit",
+ "@odata.type": "#Chassis.v1_3_0.Chassis",
+ "Model": "x86_64-accton_asfx816bbx_0716-ec",
+ "PowerState": "On",
+ "Actions": {
+ "#Chassis.Reset": {
+ "target": "/redfish/v1/Chassis/1/Actions/Chassis.Reset",
+ "ResetType@Redfish.AllowableValues": [
+ "ForceOff",
+ "GracefulShutdown",
+ "GracefulRestart",
+ "ForceRestart"
+ ]
+ }
+ },
+ "Thermal": {
+ "@odata.id": "/redfish/v1/Chassis/1/Thermal"
+ },
+ "Description": "",
+ "@odata.id": "/redfish/v1/Chassis/1",
+ "SKU": null,
+ "@odata.context": "/redfish/v1/$metadata#Chassis.Chassis",
+ "Status": {
+ "State": "Enabled",
+ "HealthRollup": "OK",
+ "Health": "OK"
+ },
+ "Manufacturer": "Accton",
+ "ChassisType": "Drawer",
+ "Oem": {
+ "Intel_RackScale": {
+ "Location": {
+ "ParentId": null,
+ "Id": null
+ },
+ "@odata.type": "#Intel.Oem.Chassis",
+ "Accton_Oem": {
+ "ServiceTag": ""
+ }
+ }
+ },
+ "AssetTag": "N/A",
+ "PartNumber": ""
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/Chassis/index.json b/mock-redfish-server/mockup/redfish/v1/Chassis/index.json
new file mode 100644
index 0000000..8b246b0
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/Chassis/index.json
@@ -0,0 +1,13 @@
+{
+ "@odata.type": "#ChassisCollection.ChassisCollection",
+ "Name": "Chassis Collection",
+ "@odata.context": "/redfish/v1/$metadata#Chassis.Chassis",
+ "Members": [
+ {
+ "@odata.id": "/redfish/v1/Chassis/1"
+ }
+ ],
+ "Description": "Collection of Chassis",
+ "@odata.id": "/redfish/v1/Chassis",
+ "Members@odata.count": 1
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/ACLs/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/ACLs/index.json
new file mode 100644
index 0000000..a443f59
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/ACLs/index.json
@@ -0,0 +1,9 @@
+{
+ "@odata.type": "#EthernetSwitchACLCollection.EthernetSwitchACLCollection",
+ "Name": "Ethernet Switch Access Control List Collection",
+ "@odata.context": "/redfish/v1/$metadata#EthernetSwitchACLCollection.EthernetSwitchACLCollection",
+ "Members": [],
+ "Description": "Switch Access Control List. Each ACL entry can be bound to any switch port",
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/ACLs",
+ "Members@odata.count": 0
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/1/StaticMACs/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/1/StaticMACs/index.json
new file mode 100644
index 0000000..02e3787
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/1/StaticMACs/index.json
@@ -0,0 +1,9 @@
+{
+ "@odata.type": "#EthernetSwitchStaticMACCollection.EthernetSwitchStaticMACCollection",
+ "Name": "Static MAC Collection",
+ "@odata.context": "/redfish/v1/$metadata#EthernetSwitchStaticMACCollection.EthernetSwitchStaticMACCollection",
+ "Members": [],
+ "Description": "Collection of Static MACs",
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/1/StaticMACs",
+ "Members@odata.count": 0
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/1/VLANs/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/1/VLANs/index.json
new file mode 100644
index 0000000..9d150e1
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/1/VLANs/index.json
@@ -0,0 +1,9 @@
+{
+ "@odata.type": "#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection",
+ "Name": "VLAN Network Interface Collection",
+ "@odata.context": "/redfish/v1/$metadata#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection",
+ "Members": [],
+ "Description": "Collection of VLAN Network Interfaces",
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/1/VLANs",
+ "Members@odata.count": 0
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/1/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/1/index.json
new file mode 100644
index 0000000..756c557
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/1/index.json
@@ -0,0 +1,124 @@
+{
+ "Name": "Port1",
+ "MACAddress": null,
+ "Statistics": {},
+ "TransceiverStatistics": {
+ "BiasCurrent": {
+ "LowerThresholdFatal": 0,
+ "LowerThresholdCritical": 0.5,
+ "Status": {
+ "State": "Enabled",
+ "Health": "OK"
+ },
+ "Reading": 41.154,
+ "ReadingUnits": "mA",
+ "UpperThresholdFatal": 70,
+ "UpperThresholdCritical": 65
+ },
+ "TxPower": {
+ "LowerThresholdFatal": 0.5,
+ "LowerThresholdCritical": 0.629,
+ "Status": {
+ "State": "Enabled",
+ "Health": "OK"
+ },
+ "Reading": 1.278,
+ "ReadingUnits": "mW",
+ "UpperThresholdFatal": 3.154,
+ "UpperThresholdCritical": 2.505
+ },
+ "Voltage": {
+ "LowerThresholdFatal": 2.97,
+ "LowerThresholdCritical": 3.129,
+ "Status": {
+ "State": "Enabled",
+ "Health": "OK"
+ },
+ "Reading": 3.33,
+ "ReadingUnits": "V",
+ "UpperThresholdFatal": 3.629,
+ "UpperThresholdCritical": 3.47
+ },
+ "Serial Number": "",
+ "SFP Vendor Name": "",
+ "RxPower": {
+ "LowerThresholdFatal": 0,
+ "LowerThresholdCritical": 0.001,
+ "Status": {
+ "State": "Enabled",
+ "Health": "Warning"
+ },
+ "Reading": 0,
+ "ReadingUnits": "mW",
+ "UpperThresholdFatal": 0.372,
+ "UpperThresholdCritical": 0.316
+ },
+ "Manufacture Date": "",
+ "Temperature": {
+ "LowerThresholdFatal": -15,
+ "LowerThresholdCritical": -8,
+ "Status": {
+ "State": "Enabled",
+ "Health": "OK"
+ },
+ "Reading": 30.476,
+ "ReadingUnits": "Celsius",
+ "UpperThresholdFatal": 85,
+ "UpperThresholdCritical": 78
+ },
+ "Part Number": ""
+ },
+ "OperationalState": "Up",
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/1",
+ "NeighborMAC": null,
+ "VLANs": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/1/VLANs"
+ },
+ "LinkType": "Ethernet",
+ "Oem": {},
+ "FrameSize": null,
+ "PortClass": null,
+ "FullDuplex": null,
+ "StaticMACs": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/1/StaticMACs"
+ },
+ "PortId": "PON port",
+ "Links": {
+ "Switch": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1"
+ },
+ "ActiveACLs": [],
+ "PortMembers": [],
+ "PrimaryVLAN": null,
+ "Oem": {
+ "Intel_RackScale": {
+ "@odata.type": "#Intel.Oem.EthernetSwitchPort"
+ }
+ },
+ "MemberOfPort": null
+ },
+ "Id": "1",
+ "Description": "Ethernet Switch Port description",
+ "ONUs": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/1/ONUs"
+ },
+ "IPv4Addresses": [],
+ "PortMode": null,
+ "LinkSpeedMbps": null,
+ "@odata.type": "#EthernetSwitchPort.v1_0_0.EthernetSwitchPort",
+ "IPv6Addresses": [],
+ "@odata.context": "/redfish/v1/$metadata#EthernetSwitchPort.EthernetSwitchPort",
+ "Status": {
+ "State": "Enabled",
+ "HealthRollup": "OK",
+ "Health": "OK"
+ },
+ "Autosense": null,
+ "AdministrativeState": "Down",
+ "PortType": null,
+ "NeighborInfo": {
+ "CableId": null,
+ "SwitchId": null,
+ "PortId": null
+ }
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/10/StaticMACs/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/10/StaticMACs/index.json
new file mode 100644
index 0000000..2c2579b
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/10/StaticMACs/index.json
@@ -0,0 +1,9 @@
+{
+ "@odata.type": "#EthernetSwitchStaticMACCollection.EthernetSwitchStaticMACCollection",
+ "Name": "Static MAC Collection",
+ "@odata.context": "/redfish/v1/$metadata#EthernetSwitchStaticMACCollection.EthernetSwitchStaticMACCollection",
+ "Members": [],
+ "Description": "Collection of Static MACs",
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/10/StaticMACs",
+ "Members@odata.count": 0
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/10/VLANs/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/10/VLANs/index.json
new file mode 100644
index 0000000..1f8b3d4
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/10/VLANs/index.json
@@ -0,0 +1,9 @@
+{
+ "@odata.type": "#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection",
+ "Name": "VLAN Network Interface Collection",
+ "@odata.context": "/redfish/v1/$metadata#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection",
+ "Members": [],
+ "Description": "Collection of VLAN Network Interfaces",
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/10/VLANs",
+ "Members@odata.count": 0
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/10/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/10/index.json
new file mode 100644
index 0000000..7b5e879
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/10/index.json
@@ -0,0 +1,54 @@
+{
+ "Name": "Port10",
+ "MACAddress": null,
+ "OperationalState": null,
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/10",
+ "NeighborMAC": null,
+ "VLANs": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/10/VLANs"
+ },
+ "LinkType": null,
+ "Oem": {},
+ "FrameSize": null,
+ "PortClass": null,
+ "FullDuplex": null,
+ "StaticMACs": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/10/StaticMACs"
+ },
+ "PortId": "PON port",
+ "Links": {
+ "Switch": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1"
+ },
+ "ActiveACLs": [],
+ "PortMembers": [],
+ "PrimaryVLAN": null,
+ "Oem": {
+ "Intel_RackScale": {
+ "@odata.type": "#Intel.Oem.EthernetSwitchPort"
+ }
+ },
+ "MemberOfPort": null
+ },
+ "Id": "10",
+ "Description": "Ethernet Switch Port description",
+ "IPv4Addresses": [],
+ "PortMode": null,
+ "LinkSpeedMbps": null,
+ "@odata.type": "#EthernetSwitchPort.v1_0_0.EthernetSwitchPort",
+ "IPv6Addresses": [],
+ "@odata.context": "/redfish/v1/$metadata#EthernetSwitchPort.EthernetSwitchPort",
+ "Status": {
+ "State": "Absent",
+ "HealthRollup": "OK",
+ "Health": "Warning"
+ },
+ "Autosense": null,
+ "AdministrativeState": null,
+ "PortType": null,
+ "NeighborInfo": {
+ "CableId": null,
+ "SwitchId": null,
+ "PortId": null
+ }
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/11/StaticMACs/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/11/StaticMACs/index.json
new file mode 100644
index 0000000..fdcf96f
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/11/StaticMACs/index.json
@@ -0,0 +1,9 @@
+{
+ "@odata.type": "#EthernetSwitchStaticMACCollection.EthernetSwitchStaticMACCollection",
+ "Name": "Static MAC Collection",
+ "@odata.context": "/redfish/v1/$metadata#EthernetSwitchStaticMACCollection.EthernetSwitchStaticMACCollection",
+ "Members": [],
+ "Description": "Collection of Static MACs",
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/11/StaticMACs",
+ "Members@odata.count": 0
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/11/VLANs/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/11/VLANs/index.json
new file mode 100644
index 0000000..bf364ac
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/11/VLANs/index.json
@@ -0,0 +1,9 @@
+{
+ "@odata.type": "#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection",
+ "Name": "VLAN Network Interface Collection",
+ "@odata.context": "/redfish/v1/$metadata#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection",
+ "Members": [],
+ "Description": "Collection of VLAN Network Interfaces",
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/11/VLANs",
+ "Members@odata.count": 0
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/11/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/11/index.json
new file mode 100644
index 0000000..4ab3ef6
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/11/index.json
@@ -0,0 +1,54 @@
+{
+ "Name": "Port11",
+ "MACAddress": null,
+ "OperationalState": null,
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/11",
+ "NeighborMAC": null,
+ "VLANs": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/11/VLANs"
+ },
+ "LinkType": null,
+ "Oem": {},
+ "FrameSize": null,
+ "PortClass": null,
+ "FullDuplex": null,
+ "StaticMACs": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/11/StaticMACs"
+ },
+ "PortId": "PON port",
+ "Links": {
+ "Switch": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1"
+ },
+ "ActiveACLs": [],
+ "PortMembers": [],
+ "PrimaryVLAN": null,
+ "Oem": {
+ "Intel_RackScale": {
+ "@odata.type": "#Intel.Oem.EthernetSwitchPort"
+ }
+ },
+ "MemberOfPort": null
+ },
+ "Id": "11",
+ "Description": "Ethernet Switch Port description",
+ "IPv4Addresses": [],
+ "PortMode": null,
+ "LinkSpeedMbps": null,
+ "@odata.type": "#EthernetSwitchPort.v1_0_0.EthernetSwitchPort",
+ "IPv6Addresses": [],
+ "@odata.context": "/redfish/v1/$metadata#EthernetSwitchPort.EthernetSwitchPort",
+ "Status": {
+ "State": "Absent",
+ "HealthRollup": "OK",
+ "Health": "Warning"
+ },
+ "Autosense": null,
+ "AdministrativeState": null,
+ "PortType": null,
+ "NeighborInfo": {
+ "CableId": null,
+ "SwitchId": null,
+ "PortId": null
+ }
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/12/StaticMACs/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/12/StaticMACs/index.json
new file mode 100644
index 0000000..dc3a3f9
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/12/StaticMACs/index.json
@@ -0,0 +1,9 @@
+{
+ "@odata.type": "#EthernetSwitchStaticMACCollection.EthernetSwitchStaticMACCollection",
+ "Name": "Static MAC Collection",
+ "@odata.context": "/redfish/v1/$metadata#EthernetSwitchStaticMACCollection.EthernetSwitchStaticMACCollection",
+ "Members": [],
+ "Description": "Collection of Static MACs",
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/12/StaticMACs",
+ "Members@odata.count": 0
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/12/VLANs/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/12/VLANs/index.json
new file mode 100644
index 0000000..faa4212
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/12/VLANs/index.json
@@ -0,0 +1,9 @@
+{
+ "@odata.type": "#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection",
+ "Name": "VLAN Network Interface Collection",
+ "@odata.context": "/redfish/v1/$metadata#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection",
+ "Members": [],
+ "Description": "Collection of VLAN Network Interfaces",
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/12/VLANs",
+ "Members@odata.count": 0
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/12/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/12/index.json
new file mode 100644
index 0000000..a82a42d
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/12/index.json
@@ -0,0 +1,124 @@
+{
+ "Name": "Port12",
+ "MACAddress": null,
+ "Statistics": {},
+ "TransceiverStatistics": {
+ "BiasCurrent": {
+ "LowerThresholdFatal": 10,
+ "LowerThresholdCritical": 20,
+ "Status": {
+ "State": "Enabled",
+ "Health": "OK"
+ },
+ "Reading": 92.906,
+ "ReadingUnits": "mA",
+ "UpperThresholdFatal": 130,
+ "UpperThresholdCritical": 120
+ },
+ "TxPower": {
+ "LowerThresholdFatal": 1.584,
+ "LowerThresholdCritical": 1.995,
+ "Status": {
+ "State": "Enabled",
+ "Health": "OK"
+ },
+ "Reading": 3.505,
+ "ReadingUnits": "mW",
+ "UpperThresholdFatal": 6.456,
+ "UpperThresholdCritical": 6.309
+ },
+ "Voltage": {
+ "LowerThresholdFatal": 3,
+ "LowerThresholdCritical": 3.049,
+ "Status": {
+ "State": "Enabled",
+ "Health": "OK"
+ },
+ "Reading": 3.329,
+ "ReadingUnits": "V",
+ "UpperThresholdFatal": 3.599,
+ "UpperThresholdCritical": 3.549
+ },
+ "Serial Number": "HDG2019845",
+ "SFP Vendor Name": "SOURCEPHOTONICS",
+ "RxPower": {
+ "LowerThresholdFatal": 0,
+ "LowerThresholdCritical": 0,
+ "Status": {
+ "State": "Enabled",
+ "Health": "OK"
+ },
+ "Reading": 0.009,
+ "ReadingUnits": "mW",
+ "UpperThresholdFatal": 0.316,
+ "UpperThresholdCritical": 0.225
+ },
+ "Manufacture Date": "171215",
+ "Temperature": {
+ "LowerThresholdFatal": -10,
+ "LowerThresholdCritical": -5,
+ "Status": {
+ "State": "Enabled",
+ "Health": "OK"
+ },
+ "Reading": 30.23,
+ "ReadingUnits": "Celsius",
+ "UpperThresholdFatal": 80,
+ "UpperThresholdCritical": 75
+ },
+ "Part Number": "XPPXG2N2CDFA"
+ },
+ "OperationalState": "Up",
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/12",
+ "NeighborMAC": null,
+ "VLANs": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/12/VLANs"
+ },
+ "LinkType": "Ethernet",
+ "Oem": {},
+ "FrameSize": null,
+ "PortClass": null,
+ "FullDuplex": null,
+ "StaticMACs": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/12/StaticMACs"
+ },
+ "PortId": "PON port",
+ "Links": {
+ "Switch": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1"
+ },
+ "ActiveACLs": [],
+ "PortMembers": [],
+ "PrimaryVLAN": null,
+ "Oem": {
+ "Intel_RackScale": {
+ "@odata.type": "#Intel.Oem.EthernetSwitchPort"
+ }
+ },
+ "MemberOfPort": null
+ },
+ "Id": "12",
+ "Description": "Ethernet Switch Port description",
+ "ONUs": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/12/ONUs"
+ },
+ "IPv4Addresses": [],
+ "PortMode": null,
+ "LinkSpeedMbps": null,
+ "@odata.type": "#EthernetSwitchPort.v1_0_0.EthernetSwitchPort",
+ "IPv6Addresses": [],
+ "@odata.context": "/redfish/v1/$metadata#EthernetSwitchPort.EthernetSwitchPort",
+ "Status": {
+ "State": "Enabled",
+ "HealthRollup": "OK",
+ "Health": "OK"
+ },
+ "Autosense": null,
+ "AdministrativeState": "Down",
+ "PortType": null,
+ "NeighborInfo": {
+ "CableId": null,
+ "SwitchId": null,
+ "PortId": null
+ }
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/13/StaticMACs/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/13/StaticMACs/index.json
new file mode 100644
index 0000000..7ebb0bb
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/13/StaticMACs/index.json
@@ -0,0 +1,9 @@
+{
+ "@odata.type": "#EthernetSwitchStaticMACCollection.EthernetSwitchStaticMACCollection",
+ "Name": "Static MAC Collection",
+ "@odata.context": "/redfish/v1/$metadata#EthernetSwitchStaticMACCollection.EthernetSwitchStaticMACCollection",
+ "Members": [],
+ "Description": "Collection of Static MACs",
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/13/StaticMACs",
+ "Members@odata.count": 0
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/13/VLANs/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/13/VLANs/index.json
new file mode 100644
index 0000000..e9cab48
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/13/VLANs/index.json
@@ -0,0 +1,9 @@
+{
+ "@odata.type": "#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection",
+ "Name": "VLAN Network Interface Collection",
+ "@odata.context": "/redfish/v1/$metadata#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection",
+ "Members": [],
+ "Description": "Collection of VLAN Network Interfaces",
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/13/VLANs",
+ "Members@odata.count": 0
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/13/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/13/index.json
new file mode 100644
index 0000000..f17b327
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/13/index.json
@@ -0,0 +1,54 @@
+{
+ "Name": "Port13",
+ "MACAddress": null,
+ "OperationalState": null,
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/13",
+ "NeighborMAC": null,
+ "VLANs": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/13/VLANs"
+ },
+ "LinkType": null,
+ "Oem": {},
+ "FrameSize": null,
+ "PortClass": null,
+ "FullDuplex": null,
+ "StaticMACs": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/13/StaticMACs"
+ },
+ "PortId": "PON port",
+ "Links": {
+ "Switch": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1"
+ },
+ "ActiveACLs": [],
+ "PortMembers": [],
+ "PrimaryVLAN": null,
+ "Oem": {
+ "Intel_RackScale": {
+ "@odata.type": "#Intel.Oem.EthernetSwitchPort"
+ }
+ },
+ "MemberOfPort": null
+ },
+ "Id": "13",
+ "Description": "Ethernet Switch Port description",
+ "IPv4Addresses": [],
+ "PortMode": null,
+ "LinkSpeedMbps": null,
+ "@odata.type": "#EthernetSwitchPort.v1_0_0.EthernetSwitchPort",
+ "IPv6Addresses": [],
+ "@odata.context": "/redfish/v1/$metadata#EthernetSwitchPort.EthernetSwitchPort",
+ "Status": {
+ "State": "Absent",
+ "HealthRollup": "OK",
+ "Health": "Warning"
+ },
+ "Autosense": null,
+ "AdministrativeState": null,
+ "PortType": null,
+ "NeighborInfo": {
+ "CableId": null,
+ "SwitchId": null,
+ "PortId": null
+ }
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/14/StaticMACs/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/14/StaticMACs/index.json
new file mode 100644
index 0000000..3e71b30
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/14/StaticMACs/index.json
@@ -0,0 +1,9 @@
+{
+ "@odata.type": "#EthernetSwitchStaticMACCollection.EthernetSwitchStaticMACCollection",
+ "Name": "Static MAC Collection",
+ "@odata.context": "/redfish/v1/$metadata#EthernetSwitchStaticMACCollection.EthernetSwitchStaticMACCollection",
+ "Members": [],
+ "Description": "Collection of Static MACs",
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/14/StaticMACs",
+ "Members@odata.count": 0
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/14/VLANs/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/14/VLANs/index.json
new file mode 100644
index 0000000..150757e
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/14/VLANs/index.json
@@ -0,0 +1,9 @@
+{
+ "@odata.type": "#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection",
+ "Name": "VLAN Network Interface Collection",
+ "@odata.context": "/redfish/v1/$metadata#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection",
+ "Members": [],
+ "Description": "Collection of VLAN Network Interfaces",
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/14/VLANs",
+ "Members@odata.count": 0
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/14/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/14/index.json
new file mode 100644
index 0000000..751f7c2
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/14/index.json
@@ -0,0 +1,54 @@
+{
+ "Name": "Port14",
+ "MACAddress": null,
+ "OperationalState": null,
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/14",
+ "NeighborMAC": null,
+ "VLANs": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/14/VLANs"
+ },
+ "LinkType": null,
+ "Oem": {},
+ "FrameSize": null,
+ "PortClass": null,
+ "FullDuplex": null,
+ "StaticMACs": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/14/StaticMACs"
+ },
+ "PortId": "PON port",
+ "Links": {
+ "Switch": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1"
+ },
+ "ActiveACLs": [],
+ "PortMembers": [],
+ "PrimaryVLAN": null,
+ "Oem": {
+ "Intel_RackScale": {
+ "@odata.type": "#Intel.Oem.EthernetSwitchPort"
+ }
+ },
+ "MemberOfPort": null
+ },
+ "Id": "14",
+ "Description": "Ethernet Switch Port description",
+ "IPv4Addresses": [],
+ "PortMode": null,
+ "LinkSpeedMbps": null,
+ "@odata.type": "#EthernetSwitchPort.v1_0_0.EthernetSwitchPort",
+ "IPv6Addresses": [],
+ "@odata.context": "/redfish/v1/$metadata#EthernetSwitchPort.EthernetSwitchPort",
+ "Status": {
+ "State": "Absent",
+ "HealthRollup": "OK",
+ "Health": "Warning"
+ },
+ "Autosense": null,
+ "AdministrativeState": null,
+ "PortType": null,
+ "NeighborInfo": {
+ "CableId": null,
+ "SwitchId": null,
+ "PortId": null
+ }
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/15/StaticMACs/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/15/StaticMACs/index.json
new file mode 100644
index 0000000..343e03d
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/15/StaticMACs/index.json
@@ -0,0 +1,9 @@
+{
+ "@odata.type": "#EthernetSwitchStaticMACCollection.EthernetSwitchStaticMACCollection",
+ "Name": "Static MAC Collection",
+ "@odata.context": "/redfish/v1/$metadata#EthernetSwitchStaticMACCollection.EthernetSwitchStaticMACCollection",
+ "Members": [],
+ "Description": "Collection of Static MACs",
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/15/StaticMACs",
+ "Members@odata.count": 0
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/15/VLANs/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/15/VLANs/index.json
new file mode 100644
index 0000000..ee9470c
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/15/VLANs/index.json
@@ -0,0 +1,9 @@
+{
+ "@odata.type": "#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection",
+ "Name": "VLAN Network Interface Collection",
+ "@odata.context": "/redfish/v1/$metadata#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection",
+ "Members": [],
+ "Description": "Collection of VLAN Network Interfaces",
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/15/VLANs",
+ "Members@odata.count": 0
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/15/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/15/index.json
new file mode 100644
index 0000000..9107f5a
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/15/index.json
@@ -0,0 +1,54 @@
+{
+ "Name": "Port15",
+ "MACAddress": null,
+ "OperationalState": null,
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/15",
+ "NeighborMAC": null,
+ "VLANs": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/15/VLANs"
+ },
+ "LinkType": null,
+ "Oem": {},
+ "FrameSize": null,
+ "PortClass": null,
+ "FullDuplex": null,
+ "StaticMACs": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/15/StaticMACs"
+ },
+ "PortId": "PON port",
+ "Links": {
+ "Switch": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1"
+ },
+ "ActiveACLs": [],
+ "PortMembers": [],
+ "PrimaryVLAN": null,
+ "Oem": {
+ "Intel_RackScale": {
+ "@odata.type": "#Intel.Oem.EthernetSwitchPort"
+ }
+ },
+ "MemberOfPort": null
+ },
+ "Id": "15",
+ "Description": "Ethernet Switch Port description",
+ "IPv4Addresses": [],
+ "PortMode": null,
+ "LinkSpeedMbps": null,
+ "@odata.type": "#EthernetSwitchPort.v1_0_0.EthernetSwitchPort",
+ "IPv6Addresses": [],
+ "@odata.context": "/redfish/v1/$metadata#EthernetSwitchPort.EthernetSwitchPort",
+ "Status": {
+ "State": "Absent",
+ "HealthRollup": "OK",
+ "Health": "Warning"
+ },
+ "Autosense": null,
+ "AdministrativeState": null,
+ "PortType": null,
+ "NeighborInfo": {
+ "CableId": null,
+ "SwitchId": null,
+ "PortId": null
+ }
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/16/StaticMACs/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/16/StaticMACs/index.json
new file mode 100644
index 0000000..3fd229c
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/16/StaticMACs/index.json
@@ -0,0 +1,9 @@
+{
+ "@odata.type": "#EthernetSwitchStaticMACCollection.EthernetSwitchStaticMACCollection",
+ "Name": "Static MAC Collection",
+ "@odata.context": "/redfish/v1/$metadata#EthernetSwitchStaticMACCollection.EthernetSwitchStaticMACCollection",
+ "Members": [],
+ "Description": "Collection of Static MACs",
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/16/StaticMACs",
+ "Members@odata.count": 0
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/16/VLANs/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/16/VLANs/index.json
new file mode 100644
index 0000000..87a29af
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/16/VLANs/index.json
@@ -0,0 +1,9 @@
+{
+ "@odata.type": "#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection",
+ "Name": "VLAN Network Interface Collection",
+ "@odata.context": "/redfish/v1/$metadata#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection",
+ "Members": [],
+ "Description": "Collection of VLAN Network Interfaces",
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/16/VLANs",
+ "Members@odata.count": 0
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/16/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/16/index.json
new file mode 100644
index 0000000..a75e05b
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/16/index.json
@@ -0,0 +1,54 @@
+{
+ "Name": "Port16",
+ "MACAddress": null,
+ "OperationalState": null,
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/16",
+ "NeighborMAC": null,
+ "VLANs": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/16/VLANs"
+ },
+ "LinkType": null,
+ "Oem": {},
+ "FrameSize": null,
+ "PortClass": null,
+ "FullDuplex": null,
+ "StaticMACs": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/16/StaticMACs"
+ },
+ "PortId": "PON port",
+ "Links": {
+ "Switch": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1"
+ },
+ "ActiveACLs": [],
+ "PortMembers": [],
+ "PrimaryVLAN": null,
+ "Oem": {
+ "Intel_RackScale": {
+ "@odata.type": "#Intel.Oem.EthernetSwitchPort"
+ }
+ },
+ "MemberOfPort": null
+ },
+ "Id": "16",
+ "Description": "Ethernet Switch Port description",
+ "IPv4Addresses": [],
+ "PortMode": null,
+ "LinkSpeedMbps": null,
+ "@odata.type": "#EthernetSwitchPort.v1_0_0.EthernetSwitchPort",
+ "IPv6Addresses": [],
+ "@odata.context": "/redfish/v1/$metadata#EthernetSwitchPort.EthernetSwitchPort",
+ "Status": {
+ "State": "Absent",
+ "HealthRollup": "OK",
+ "Health": "Warning"
+ },
+ "Autosense": null,
+ "AdministrativeState": null,
+ "PortType": null,
+ "NeighborInfo": {
+ "CableId": null,
+ "SwitchId": null,
+ "PortId": null
+ }
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/17/StaticMACs/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/17/StaticMACs/index.json
new file mode 100644
index 0000000..107f2a2
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/17/StaticMACs/index.json
@@ -0,0 +1,9 @@
+{
+ "@odata.type": "#EthernetSwitchStaticMACCollection.EthernetSwitchStaticMACCollection",
+ "Name": "Static MAC Collection",
+ "@odata.context": "/redfish/v1/$metadata#EthernetSwitchStaticMACCollection.EthernetSwitchStaticMACCollection",
+ "Members": [],
+ "Description": "Collection of Static MACs",
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/17/StaticMACs",
+ "Members@odata.count": 0
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/17/VLANs/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/17/VLANs/index.json
new file mode 100644
index 0000000..9a3f96a
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/17/VLANs/index.json
@@ -0,0 +1,9 @@
+{
+ "@odata.type": "#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection",
+ "Name": "VLAN Network Interface Collection",
+ "@odata.context": "/redfish/v1/$metadata#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection",
+ "Members": [],
+ "Description": "Collection of VLAN Network Interfaces",
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/17/VLANs",
+ "Members@odata.count": 0
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/17/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/17/index.json
new file mode 100644
index 0000000..cb43b9b
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/17/index.json
@@ -0,0 +1,134 @@
+{
+ "Name": "Port17",
+ "MACAddress": null,
+ "Statistics": {
+ "rx_bytes": 0,
+ "tx_packets": 0,
+ "tx_bcast_packets": 0,
+ "tx_mcast_packets": 0,
+ "tx_ucast_packets": 0,
+ "rx_bcast_packets": 0,
+ "tx_error_packets": 0,
+ "rx_packets": 0,
+ "rx_mcast_packets": 0,
+ "rx_ucast_packets": 0,
+ "tx_bytes": 0,
+ "rx_error_packets": 0
+ },
+ "TransceiverStatistics": {
+ "BiasCurrent": {
+ "LowerThresholdFatal": 0,
+ "LowerThresholdCritical": 0,
+ "Status": {
+ "State": null,
+ "Health": null
+ },
+ "Reading": 0,
+ "ReadingUnits": "mA",
+ "UpperThresholdFatal": 0,
+ "UpperThresholdCritical": 0
+ },
+ "TxPower": {
+ "LowerThresholdFatal": 0,
+ "LowerThresholdCritical": 0,
+ "Status": {
+ "State": null,
+ "Health": null
+ },
+ "Reading": 0,
+ "ReadingUnits": "mW",
+ "UpperThresholdFatal": 0,
+ "UpperThresholdCritical": 0
+ },
+ "Voltage": {
+ "LowerThresholdFatal": 0,
+ "LowerThresholdCritical": 0,
+ "Status": {
+ "State": null,
+ "Health": null
+ },
+ "Reading": 0,
+ "ReadingUnits": "V",
+ "UpperThresholdFatal": 0,
+ "UpperThresholdCritical": 0
+ },
+ "Serial Number": "NA",
+ "SFP Vendor Name": "NA",
+ "RxPower": {
+ "LowerThresholdFatal": 0,
+ "LowerThresholdCritical": 0,
+ "Status": {
+ "State": null,
+ "Health": null
+ },
+ "Reading": 0,
+ "ReadingUnits": "mW",
+ "UpperThresholdFatal": 0,
+ "UpperThresholdCritical": 0
+ },
+ "Manufacture Date": "NA",
+ "Temperature": {
+ "LowerThresholdFatal": 0,
+ "LowerThresholdCritical": 0,
+ "Status": {
+ "State": null,
+ "Health": null
+ },
+ "Reading": 0,
+ "ReadingUnits": "Celsius",
+ "UpperThresholdFatal": 0,
+ "UpperThresholdCritical": 0
+ },
+ "Part Number": "NA"
+ },
+ "OperationalState": "Up",
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/17",
+ "NeighborMAC": null,
+ "VLANs": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/17/VLANs"
+ },
+ "LinkType": "Ethernet",
+ "Oem": {},
+ "FrameSize": null,
+ "PortClass": null,
+ "FullDuplex": null,
+ "StaticMACs": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/17/StaticMACs"
+ },
+ "PortId": "QSFP port",
+ "Links": {
+ "Switch": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1"
+ },
+ "ActiveACLs": [],
+ "PortMembers": [],
+ "PrimaryVLAN": null,
+ "Oem": {
+ "Intel_RackScale": {
+ "@odata.type": "#Intel.Oem.EthernetSwitchPort"
+ }
+ },
+ "MemberOfPort": null
+ },
+ "Id": "17",
+ "Description": "Ethernet Switch Port description",
+ "IPv4Addresses": [],
+ "PortMode": null,
+ "LinkSpeedMbps": null,
+ "@odata.type": "#EthernetSwitchPort.v1_0_0.EthernetSwitchPort",
+ "IPv6Addresses": [],
+ "@odata.context": "/redfish/v1/$metadata#EthernetSwitchPort.EthernetSwitchPort",
+ "Status": {
+ "State": "Enabled",
+ "HealthRollup": "OK",
+ "Health": "OK"
+ },
+ "Autosense": null,
+ "AdministrativeState": "Down",
+ "PortType": null,
+ "NeighborInfo": {
+ "CableId": null,
+ "SwitchId": null,
+ "PortId": null
+ }
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/18/StaticMACs/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/18/StaticMACs/index.json
new file mode 100644
index 0000000..9c898c8
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/18/StaticMACs/index.json
@@ -0,0 +1,9 @@
+{
+ "@odata.type": "#EthernetSwitchStaticMACCollection.EthernetSwitchStaticMACCollection",
+ "Name": "Static MAC Collection",
+ "@odata.context": "/redfish/v1/$metadata#EthernetSwitchStaticMACCollection.EthernetSwitchStaticMACCollection",
+ "Members": [],
+ "Description": "Collection of Static MACs",
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/18/StaticMACs",
+ "Members@odata.count": 0
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/18/VLANs/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/18/VLANs/index.json
new file mode 100644
index 0000000..f2c6d67
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/18/VLANs/index.json
@@ -0,0 +1,9 @@
+{
+ "@odata.type": "#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection",
+ "Name": "VLAN Network Interface Collection",
+ "@odata.context": "/redfish/v1/$metadata#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection",
+ "Members": [],
+ "Description": "Collection of VLAN Network Interfaces",
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/18/VLANs",
+ "Members@odata.count": 0
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/18/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/18/index.json
new file mode 100644
index 0000000..682f736
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/18/index.json
@@ -0,0 +1,54 @@
+{
+ "Name": "Port18",
+ "MACAddress": null,
+ "OperationalState": null,
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/18",
+ "NeighborMAC": null,
+ "VLANs": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/18/VLANs"
+ },
+ "LinkType": null,
+ "Oem": {},
+ "FrameSize": null,
+ "PortClass": null,
+ "FullDuplex": null,
+ "StaticMACs": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/18/StaticMACs"
+ },
+ "PortId": "QSFP port",
+ "Links": {
+ "Switch": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1"
+ },
+ "ActiveACLs": [],
+ "PortMembers": [],
+ "PrimaryVLAN": null,
+ "Oem": {
+ "Intel_RackScale": {
+ "@odata.type": "#Intel.Oem.EthernetSwitchPort"
+ }
+ },
+ "MemberOfPort": null
+ },
+ "Id": "18",
+ "Description": "Ethernet Switch Port description",
+ "IPv4Addresses": [],
+ "PortMode": null,
+ "LinkSpeedMbps": null,
+ "@odata.type": "#EthernetSwitchPort.v1_0_0.EthernetSwitchPort",
+ "IPv6Addresses": [],
+ "@odata.context": "/redfish/v1/$metadata#EthernetSwitchPort.EthernetSwitchPort",
+ "Status": {
+ "State": "Absent",
+ "HealthRollup": "OK",
+ "Health": "Warning"
+ },
+ "Autosense": null,
+ "AdministrativeState": null,
+ "PortType": null,
+ "NeighborInfo": {
+ "CableId": null,
+ "SwitchId": null,
+ "PortId": null
+ }
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/19/StaticMACs/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/19/StaticMACs/index.json
new file mode 100644
index 0000000..fce27b7
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/19/StaticMACs/index.json
@@ -0,0 +1,9 @@
+{
+ "@odata.type": "#EthernetSwitchStaticMACCollection.EthernetSwitchStaticMACCollection",
+ "Name": "Static MAC Collection",
+ "@odata.context": "/redfish/v1/$metadata#EthernetSwitchStaticMACCollection.EthernetSwitchStaticMACCollection",
+ "Members": [],
+ "Description": "Collection of Static MACs",
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/19/StaticMACs",
+ "Members@odata.count": 0
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/19/VLANs/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/19/VLANs/index.json
new file mode 100644
index 0000000..5e38d1c
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/19/VLANs/index.json
@@ -0,0 +1,9 @@
+{
+ "@odata.type": "#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection",
+ "Name": "VLAN Network Interface Collection",
+ "@odata.context": "/redfish/v1/$metadata#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection",
+ "Members": [],
+ "Description": "Collection of VLAN Network Interfaces",
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/19/VLANs",
+ "Members@odata.count": 0
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/19/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/19/index.json
new file mode 100644
index 0000000..02c0416
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/19/index.json
@@ -0,0 +1,54 @@
+{
+ "Name": "Port19",
+ "MACAddress": null,
+ "OperationalState": null,
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/19",
+ "NeighborMAC": null,
+ "VLANs": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/19/VLANs"
+ },
+ "LinkType": null,
+ "Oem": {},
+ "FrameSize": null,
+ "PortClass": null,
+ "FullDuplex": null,
+ "StaticMACs": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/19/StaticMACs"
+ },
+ "PortId": "QSFP port",
+ "Links": {
+ "Switch": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1"
+ },
+ "ActiveACLs": [],
+ "PortMembers": [],
+ "PrimaryVLAN": null,
+ "Oem": {
+ "Intel_RackScale": {
+ "@odata.type": "#Intel.Oem.EthernetSwitchPort"
+ }
+ },
+ "MemberOfPort": null
+ },
+ "Id": "19",
+ "Description": "Ethernet Switch Port description",
+ "IPv4Addresses": [],
+ "PortMode": null,
+ "LinkSpeedMbps": null,
+ "@odata.type": "#EthernetSwitchPort.v1_0_0.EthernetSwitchPort",
+ "IPv6Addresses": [],
+ "@odata.context": "/redfish/v1/$metadata#EthernetSwitchPort.EthernetSwitchPort",
+ "Status": {
+ "State": "Absent",
+ "HealthRollup": "OK",
+ "Health": "Warning"
+ },
+ "Autosense": null,
+ "AdministrativeState": null,
+ "PortType": null,
+ "NeighborInfo": {
+ "CableId": null,
+ "SwitchId": null,
+ "PortId": null
+ }
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/2/StaticMACs/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/2/StaticMACs/index.json
new file mode 100644
index 0000000..54c3b73
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/2/StaticMACs/index.json
@@ -0,0 +1,9 @@
+{
+ "@odata.type": "#EthernetSwitchStaticMACCollection.EthernetSwitchStaticMACCollection",
+ "Name": "Static MAC Collection",
+ "@odata.context": "/redfish/v1/$metadata#EthernetSwitchStaticMACCollection.EthernetSwitchStaticMACCollection",
+ "Members": [],
+ "Description": "Collection of Static MACs",
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/2/StaticMACs",
+ "Members@odata.count": 0
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/2/VLANs/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/2/VLANs/index.json
new file mode 100644
index 0000000..9d3c408
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/2/VLANs/index.json
@@ -0,0 +1,9 @@
+{
+ "@odata.type": "#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection",
+ "Name": "VLAN Network Interface Collection",
+ "@odata.context": "/redfish/v1/$metadata#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection",
+ "Members": [],
+ "Description": "Collection of VLAN Network Interfaces",
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/2/VLANs",
+ "Members@odata.count": 0
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/2/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/2/index.json
new file mode 100644
index 0000000..3722e52
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/2/index.json
@@ -0,0 +1,54 @@
+{
+ "Name": "Port2",
+ "MACAddress": null,
+ "OperationalState": null,
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/2",
+ "NeighborMAC": null,
+ "VLANs": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/2/VLANs"
+ },
+ "LinkType": null,
+ "Oem": {},
+ "FrameSize": null,
+ "PortClass": null,
+ "FullDuplex": null,
+ "StaticMACs": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/2/StaticMACs"
+ },
+ "PortId": "PON port",
+ "Links": {
+ "Switch": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1"
+ },
+ "ActiveACLs": [],
+ "PortMembers": [],
+ "PrimaryVLAN": null,
+ "Oem": {
+ "Intel_RackScale": {
+ "@odata.type": "#Intel.Oem.EthernetSwitchPort"
+ }
+ },
+ "MemberOfPort": null
+ },
+ "Id": "2",
+ "Description": "Ethernet Switch Port description",
+ "IPv4Addresses": [],
+ "PortMode": null,
+ "LinkSpeedMbps": null,
+ "@odata.type": "#EthernetSwitchPort.v1_0_0.EthernetSwitchPort",
+ "IPv6Addresses": [],
+ "@odata.context": "/redfish/v1/$metadata#EthernetSwitchPort.EthernetSwitchPort",
+ "Status": {
+ "State": "Absent",
+ "HealthRollup": "OK",
+ "Health": "Warning"
+ },
+ "Autosense": null,
+ "AdministrativeState": null,
+ "PortType": null,
+ "NeighborInfo": {
+ "CableId": null,
+ "SwitchId": null,
+ "PortId": null
+ }
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/20/StaticMACs/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/20/StaticMACs/index.json
new file mode 100644
index 0000000..5ef1a43
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/20/StaticMACs/index.json
@@ -0,0 +1,9 @@
+{
+ "@odata.type": "#EthernetSwitchStaticMACCollection.EthernetSwitchStaticMACCollection",
+ "Name": "Static MAC Collection",
+ "@odata.context": "/redfish/v1/$metadata#EthernetSwitchStaticMACCollection.EthernetSwitchStaticMACCollection",
+ "Members": [],
+ "Description": "Collection of Static MACs",
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/20/StaticMACs",
+ "Members@odata.count": 0
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/20/VLANs/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/20/VLANs/index.json
new file mode 100644
index 0000000..116ecef
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/20/VLANs/index.json
@@ -0,0 +1,9 @@
+{
+ "@odata.type": "#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection",
+ "Name": "VLAN Network Interface Collection",
+ "@odata.context": "/redfish/v1/$metadata#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection",
+ "Members": [],
+ "Description": "Collection of VLAN Network Interfaces",
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/20/VLANs",
+ "Members@odata.count": 0
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/20/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/20/index.json
new file mode 100644
index 0000000..1b58f1b
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/20/index.json
@@ -0,0 +1,54 @@
+{
+ "Name": "Port20",
+ "MACAddress": null,
+ "OperationalState": null,
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/20",
+ "NeighborMAC": null,
+ "VLANs": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/20/VLANs"
+ },
+ "LinkType": null,
+ "Oem": {},
+ "FrameSize": null,
+ "PortClass": null,
+ "FullDuplex": null,
+ "StaticMACs": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/20/StaticMACs"
+ },
+ "PortId": "QSFP port",
+ "Links": {
+ "Switch": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1"
+ },
+ "ActiveACLs": [],
+ "PortMembers": [],
+ "PrimaryVLAN": null,
+ "Oem": {
+ "Intel_RackScale": {
+ "@odata.type": "#Intel.Oem.EthernetSwitchPort"
+ }
+ },
+ "MemberOfPort": null
+ },
+ "Id": "20",
+ "Description": "Ethernet Switch Port description",
+ "IPv4Addresses": [],
+ "PortMode": null,
+ "LinkSpeedMbps": null,
+ "@odata.type": "#EthernetSwitchPort.v1_0_0.EthernetSwitchPort",
+ "IPv6Addresses": [],
+ "@odata.context": "/redfish/v1/$metadata#EthernetSwitchPort.EthernetSwitchPort",
+ "Status": {
+ "State": "Absent",
+ "HealthRollup": "OK",
+ "Health": "Warning"
+ },
+ "Autosense": null,
+ "AdministrativeState": null,
+ "PortType": null,
+ "NeighborInfo": {
+ "CableId": null,
+ "SwitchId": null,
+ "PortId": null
+ }
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/3/StaticMACs/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/3/StaticMACs/index.json
new file mode 100644
index 0000000..c4218a1
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/3/StaticMACs/index.json
@@ -0,0 +1,9 @@
+{
+ "@odata.type": "#EthernetSwitchStaticMACCollection.EthernetSwitchStaticMACCollection",
+ "Name": "Static MAC Collection",
+ "@odata.context": "/redfish/v1/$metadata#EthernetSwitchStaticMACCollection.EthernetSwitchStaticMACCollection",
+ "Members": [],
+ "Description": "Collection of Static MACs",
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/3/StaticMACs",
+ "Members@odata.count": 0
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/3/VLANs/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/3/VLANs/index.json
new file mode 100644
index 0000000..7cf1cd8
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/3/VLANs/index.json
@@ -0,0 +1,9 @@
+{
+ "@odata.type": "#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection",
+ "Name": "VLAN Network Interface Collection",
+ "@odata.context": "/redfish/v1/$metadata#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection",
+ "Members": [],
+ "Description": "Collection of VLAN Network Interfaces",
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/3/VLANs",
+ "Members@odata.count": 0
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/3/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/3/index.json
new file mode 100644
index 0000000..f6c1adf
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/3/index.json
@@ -0,0 +1,54 @@
+{
+ "Name": "Port3",
+ "MACAddress": null,
+ "OperationalState": null,
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/3",
+ "NeighborMAC": null,
+ "VLANs": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/3/VLANs"
+ },
+ "LinkType": null,
+ "Oem": {},
+ "FrameSize": null,
+ "PortClass": null,
+ "FullDuplex": null,
+ "StaticMACs": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/3/StaticMACs"
+ },
+ "PortId": "PON port",
+ "Links": {
+ "Switch": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1"
+ },
+ "ActiveACLs": [],
+ "PortMembers": [],
+ "PrimaryVLAN": null,
+ "Oem": {
+ "Intel_RackScale": {
+ "@odata.type": "#Intel.Oem.EthernetSwitchPort"
+ }
+ },
+ "MemberOfPort": null
+ },
+ "Id": "3",
+ "Description": "Ethernet Switch Port description",
+ "IPv4Addresses": [],
+ "PortMode": null,
+ "LinkSpeedMbps": null,
+ "@odata.type": "#EthernetSwitchPort.v1_0_0.EthernetSwitchPort",
+ "IPv6Addresses": [],
+ "@odata.context": "/redfish/v1/$metadata#EthernetSwitchPort.EthernetSwitchPort",
+ "Status": {
+ "State": "Absent",
+ "HealthRollup": "OK",
+ "Health": "Warning"
+ },
+ "Autosense": null,
+ "AdministrativeState": null,
+ "PortType": null,
+ "NeighborInfo": {
+ "CableId": null,
+ "SwitchId": null,
+ "PortId": null
+ }
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/4/StaticMACs/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/4/StaticMACs/index.json
new file mode 100644
index 0000000..b6f0398
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/4/StaticMACs/index.json
@@ -0,0 +1,9 @@
+{
+ "@odata.type": "#EthernetSwitchStaticMACCollection.EthernetSwitchStaticMACCollection",
+ "Name": "Static MAC Collection",
+ "@odata.context": "/redfish/v1/$metadata#EthernetSwitchStaticMACCollection.EthernetSwitchStaticMACCollection",
+ "Members": [],
+ "Description": "Collection of Static MACs",
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/4/StaticMACs",
+ "Members@odata.count": 0
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/4/VLANs/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/4/VLANs/index.json
new file mode 100644
index 0000000..4574f95
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/4/VLANs/index.json
@@ -0,0 +1,9 @@
+{
+ "@odata.type": "#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection",
+ "Name": "VLAN Network Interface Collection",
+ "@odata.context": "/redfish/v1/$metadata#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection",
+ "Members": [],
+ "Description": "Collection of VLAN Network Interfaces",
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/4/VLANs",
+ "Members@odata.count": 0
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/4/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/4/index.json
new file mode 100644
index 0000000..b3f6a1f
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/4/index.json
@@ -0,0 +1,54 @@
+{
+ "Name": "Port4",
+ "MACAddress": null,
+ "OperationalState": null,
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/4",
+ "NeighborMAC": null,
+ "VLANs": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/4/VLANs"
+ },
+ "LinkType": null,
+ "Oem": {},
+ "FrameSize": null,
+ "PortClass": null,
+ "FullDuplex": null,
+ "StaticMACs": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/4/StaticMACs"
+ },
+ "PortId": "PON port",
+ "Links": {
+ "Switch": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1"
+ },
+ "ActiveACLs": [],
+ "PortMembers": [],
+ "PrimaryVLAN": null,
+ "Oem": {
+ "Intel_RackScale": {
+ "@odata.type": "#Intel.Oem.EthernetSwitchPort"
+ }
+ },
+ "MemberOfPort": null
+ },
+ "Id": "4",
+ "Description": "Ethernet Switch Port description",
+ "IPv4Addresses": [],
+ "PortMode": null,
+ "LinkSpeedMbps": null,
+ "@odata.type": "#EthernetSwitchPort.v1_0_0.EthernetSwitchPort",
+ "IPv6Addresses": [],
+ "@odata.context": "/redfish/v1/$metadata#EthernetSwitchPort.EthernetSwitchPort",
+ "Status": {
+ "State": "Absent",
+ "HealthRollup": "OK",
+ "Health": "Warning"
+ },
+ "Autosense": null,
+ "AdministrativeState": null,
+ "PortType": null,
+ "NeighborInfo": {
+ "CableId": null,
+ "SwitchId": null,
+ "PortId": null
+ }
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/5/StaticMACs/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/5/StaticMACs/index.json
new file mode 100644
index 0000000..aa0d86b
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/5/StaticMACs/index.json
@@ -0,0 +1,9 @@
+{
+ "@odata.type": "#EthernetSwitchStaticMACCollection.EthernetSwitchStaticMACCollection",
+ "Name": "Static MAC Collection",
+ "@odata.context": "/redfish/v1/$metadata#EthernetSwitchStaticMACCollection.EthernetSwitchStaticMACCollection",
+ "Members": [],
+ "Description": "Collection of Static MACs",
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/5/StaticMACs",
+ "Members@odata.count": 0
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/5/VLANs/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/5/VLANs/index.json
new file mode 100644
index 0000000..4facec5
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/5/VLANs/index.json
@@ -0,0 +1,9 @@
+{
+ "@odata.type": "#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection",
+ "Name": "VLAN Network Interface Collection",
+ "@odata.context": "/redfish/v1/$metadata#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection",
+ "Members": [],
+ "Description": "Collection of VLAN Network Interfaces",
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/5/VLANs",
+ "Members@odata.count": 0
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/5/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/5/index.json
new file mode 100644
index 0000000..ff24333
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/5/index.json
@@ -0,0 +1,54 @@
+{
+ "Name": "Port5",
+ "MACAddress": null,
+ "OperationalState": null,
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/5",
+ "NeighborMAC": null,
+ "VLANs": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/5/VLANs"
+ },
+ "LinkType": null,
+ "Oem": {},
+ "FrameSize": null,
+ "PortClass": null,
+ "FullDuplex": null,
+ "StaticMACs": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/5/StaticMACs"
+ },
+ "PortId": "PON port",
+ "Links": {
+ "Switch": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1"
+ },
+ "ActiveACLs": [],
+ "PortMembers": [],
+ "PrimaryVLAN": null,
+ "Oem": {
+ "Intel_RackScale": {
+ "@odata.type": "#Intel.Oem.EthernetSwitchPort"
+ }
+ },
+ "MemberOfPort": null
+ },
+ "Id": "5",
+ "Description": "Ethernet Switch Port description",
+ "IPv4Addresses": [],
+ "PortMode": null,
+ "LinkSpeedMbps": null,
+ "@odata.type": "#EthernetSwitchPort.v1_0_0.EthernetSwitchPort",
+ "IPv6Addresses": [],
+ "@odata.context": "/redfish/v1/$metadata#EthernetSwitchPort.EthernetSwitchPort",
+ "Status": {
+ "State": "Absent",
+ "HealthRollup": "OK",
+ "Health": "Warning"
+ },
+ "Autosense": null,
+ "AdministrativeState": null,
+ "PortType": null,
+ "NeighborInfo": {
+ "CableId": null,
+ "SwitchId": null,
+ "PortId": null
+ }
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/6/StaticMACs/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/6/StaticMACs/index.json
new file mode 100644
index 0000000..2d74d82
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/6/StaticMACs/index.json
@@ -0,0 +1,9 @@
+{
+ "@odata.type": "#EthernetSwitchStaticMACCollection.EthernetSwitchStaticMACCollection",
+ "Name": "Static MAC Collection",
+ "@odata.context": "/redfish/v1/$metadata#EthernetSwitchStaticMACCollection.EthernetSwitchStaticMACCollection",
+ "Members": [],
+ "Description": "Collection of Static MACs",
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/6/StaticMACs",
+ "Members@odata.count": 0
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/6/VLANs/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/6/VLANs/index.json
new file mode 100644
index 0000000..5e0541f
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/6/VLANs/index.json
@@ -0,0 +1,9 @@
+{
+ "@odata.type": "#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection",
+ "Name": "VLAN Network Interface Collection",
+ "@odata.context": "/redfish/v1/$metadata#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection",
+ "Members": [],
+ "Description": "Collection of VLAN Network Interfaces",
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/6/VLANs",
+ "Members@odata.count": 0
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/6/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/6/index.json
new file mode 100644
index 0000000..5233526
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/6/index.json
@@ -0,0 +1,54 @@
+{
+ "Name": "Port6",
+ "MACAddress": null,
+ "OperationalState": null,
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/6",
+ "NeighborMAC": null,
+ "VLANs": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/6/VLANs"
+ },
+ "LinkType": null,
+ "Oem": {},
+ "FrameSize": null,
+ "PortClass": null,
+ "FullDuplex": null,
+ "StaticMACs": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/6/StaticMACs"
+ },
+ "PortId": "PON port",
+ "Links": {
+ "Switch": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1"
+ },
+ "ActiveACLs": [],
+ "PortMembers": [],
+ "PrimaryVLAN": null,
+ "Oem": {
+ "Intel_RackScale": {
+ "@odata.type": "#Intel.Oem.EthernetSwitchPort"
+ }
+ },
+ "MemberOfPort": null
+ },
+ "Id": "6",
+ "Description": "Ethernet Switch Port description",
+ "IPv4Addresses": [],
+ "PortMode": null,
+ "LinkSpeedMbps": null,
+ "@odata.type": "#EthernetSwitchPort.v1_0_0.EthernetSwitchPort",
+ "IPv6Addresses": [],
+ "@odata.context": "/redfish/v1/$metadata#EthernetSwitchPort.EthernetSwitchPort",
+ "Status": {
+ "State": "Absent",
+ "HealthRollup": "OK",
+ "Health": "Warning"
+ },
+ "Autosense": null,
+ "AdministrativeState": null,
+ "PortType": null,
+ "NeighborInfo": {
+ "CableId": null,
+ "SwitchId": null,
+ "PortId": null
+ }
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/7/StaticMACs/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/7/StaticMACs/index.json
new file mode 100644
index 0000000..748186b
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/7/StaticMACs/index.json
@@ -0,0 +1,9 @@
+{
+ "@odata.type": "#EthernetSwitchStaticMACCollection.EthernetSwitchStaticMACCollection",
+ "Name": "Static MAC Collection",
+ "@odata.context": "/redfish/v1/$metadata#EthernetSwitchStaticMACCollection.EthernetSwitchStaticMACCollection",
+ "Members": [],
+ "Description": "Collection of Static MACs",
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/7/StaticMACs",
+ "Members@odata.count": 0
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/7/VLANs/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/7/VLANs/index.json
new file mode 100644
index 0000000..0475324
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/7/VLANs/index.json
@@ -0,0 +1,9 @@
+{
+ "@odata.type": "#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection",
+ "Name": "VLAN Network Interface Collection",
+ "@odata.context": "/redfish/v1/$metadata#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection",
+ "Members": [],
+ "Description": "Collection of VLAN Network Interfaces",
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/7/VLANs",
+ "Members@odata.count": 0
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/7/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/7/index.json
new file mode 100644
index 0000000..74c5b78
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/7/index.json
@@ -0,0 +1,54 @@
+{
+ "Name": "Port7",
+ "MACAddress": null,
+ "OperationalState": null,
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/7",
+ "NeighborMAC": null,
+ "VLANs": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/7/VLANs"
+ },
+ "LinkType": null,
+ "Oem": {},
+ "FrameSize": null,
+ "PortClass": null,
+ "FullDuplex": null,
+ "StaticMACs": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/7/StaticMACs"
+ },
+ "PortId": "PON port",
+ "Links": {
+ "Switch": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1"
+ },
+ "ActiveACLs": [],
+ "PortMembers": [],
+ "PrimaryVLAN": null,
+ "Oem": {
+ "Intel_RackScale": {
+ "@odata.type": "#Intel.Oem.EthernetSwitchPort"
+ }
+ },
+ "MemberOfPort": null
+ },
+ "Id": "7",
+ "Description": "Ethernet Switch Port description",
+ "IPv4Addresses": [],
+ "PortMode": null,
+ "LinkSpeedMbps": null,
+ "@odata.type": "#EthernetSwitchPort.v1_0_0.EthernetSwitchPort",
+ "IPv6Addresses": [],
+ "@odata.context": "/redfish/v1/$metadata#EthernetSwitchPort.EthernetSwitchPort",
+ "Status": {
+ "State": "Absent",
+ "HealthRollup": "OK",
+ "Health": "Warning"
+ },
+ "Autosense": null,
+ "AdministrativeState": null,
+ "PortType": null,
+ "NeighborInfo": {
+ "CableId": null,
+ "SwitchId": null,
+ "PortId": null
+ }
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/8/StaticMACs/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/8/StaticMACs/index.json
new file mode 100644
index 0000000..f1d81b4
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/8/StaticMACs/index.json
@@ -0,0 +1,9 @@
+{
+ "@odata.type": "#EthernetSwitchStaticMACCollection.EthernetSwitchStaticMACCollection",
+ "Name": "Static MAC Collection",
+ "@odata.context": "/redfish/v1/$metadata#EthernetSwitchStaticMACCollection.EthernetSwitchStaticMACCollection",
+ "Members": [],
+ "Description": "Collection of Static MACs",
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/8/StaticMACs",
+ "Members@odata.count": 0
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/8/VLANs/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/8/VLANs/index.json
new file mode 100644
index 0000000..06d5957
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/8/VLANs/index.json
@@ -0,0 +1,9 @@
+{
+ "@odata.type": "#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection",
+ "Name": "VLAN Network Interface Collection",
+ "@odata.context": "/redfish/v1/$metadata#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection",
+ "Members": [],
+ "Description": "Collection of VLAN Network Interfaces",
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/8/VLANs",
+ "Members@odata.count": 0
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/8/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/8/index.json
new file mode 100644
index 0000000..0e5a606
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/8/index.json
@@ -0,0 +1,54 @@
+{
+ "Name": "Port8",
+ "MACAddress": null,
+ "OperationalState": null,
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/8",
+ "NeighborMAC": null,
+ "VLANs": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/8/VLANs"
+ },
+ "LinkType": null,
+ "Oem": {},
+ "FrameSize": null,
+ "PortClass": null,
+ "FullDuplex": null,
+ "StaticMACs": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/8/StaticMACs"
+ },
+ "PortId": "PON port",
+ "Links": {
+ "Switch": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1"
+ },
+ "ActiveACLs": [],
+ "PortMembers": [],
+ "PrimaryVLAN": null,
+ "Oem": {
+ "Intel_RackScale": {
+ "@odata.type": "#Intel.Oem.EthernetSwitchPort"
+ }
+ },
+ "MemberOfPort": null
+ },
+ "Id": "8",
+ "Description": "Ethernet Switch Port description",
+ "IPv4Addresses": [],
+ "PortMode": null,
+ "LinkSpeedMbps": null,
+ "@odata.type": "#EthernetSwitchPort.v1_0_0.EthernetSwitchPort",
+ "IPv6Addresses": [],
+ "@odata.context": "/redfish/v1/$metadata#EthernetSwitchPort.EthernetSwitchPort",
+ "Status": {
+ "State": "Absent",
+ "HealthRollup": "OK",
+ "Health": "Warning"
+ },
+ "Autosense": null,
+ "AdministrativeState": null,
+ "PortType": null,
+ "NeighborInfo": {
+ "CableId": null,
+ "SwitchId": null,
+ "PortId": null
+ }
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/9/StaticMACs/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/9/StaticMACs/index.json
new file mode 100644
index 0000000..7c26584
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/9/StaticMACs/index.json
@@ -0,0 +1,9 @@
+{
+ "@odata.type": "#EthernetSwitchStaticMACCollection.EthernetSwitchStaticMACCollection",
+ "Name": "Static MAC Collection",
+ "@odata.context": "/redfish/v1/$metadata#EthernetSwitchStaticMACCollection.EthernetSwitchStaticMACCollection",
+ "Members": [],
+ "Description": "Collection of Static MACs",
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/9/StaticMACs",
+ "Members@odata.count": 0
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/9/VLANs/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/9/VLANs/index.json
new file mode 100644
index 0000000..f95e2cf
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/9/VLANs/index.json
@@ -0,0 +1,9 @@
+{
+ "@odata.type": "#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection",
+ "Name": "VLAN Network Interface Collection",
+ "@odata.context": "/redfish/v1/$metadata#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection",
+ "Members": [],
+ "Description": "Collection of VLAN Network Interfaces",
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/9/VLANs",
+ "Members@odata.count": 0
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/9/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/9/index.json
new file mode 100644
index 0000000..3c6ef6b
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/9/index.json
@@ -0,0 +1,54 @@
+{
+ "Name": "Port9",
+ "MACAddress": null,
+ "OperationalState": null,
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/9",
+ "NeighborMAC": null,
+ "VLANs": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/9/VLANs"
+ },
+ "LinkType": null,
+ "Oem": {},
+ "FrameSize": null,
+ "PortClass": null,
+ "FullDuplex": null,
+ "StaticMACs": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/9/StaticMACs"
+ },
+ "PortId": "PON port",
+ "Links": {
+ "Switch": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1"
+ },
+ "ActiveACLs": [],
+ "PortMembers": [],
+ "PrimaryVLAN": null,
+ "Oem": {
+ "Intel_RackScale": {
+ "@odata.type": "#Intel.Oem.EthernetSwitchPort"
+ }
+ },
+ "MemberOfPort": null
+ },
+ "Id": "9",
+ "Description": "Ethernet Switch Port description",
+ "IPv4Addresses": [],
+ "PortMode": null,
+ "LinkSpeedMbps": null,
+ "@odata.type": "#EthernetSwitchPort.v1_0_0.EthernetSwitchPort",
+ "IPv6Addresses": [],
+ "@odata.context": "/redfish/v1/$metadata#EthernetSwitchPort.EthernetSwitchPort",
+ "Status": {
+ "State": "Absent",
+ "HealthRollup": "OK",
+ "Health": "Warning"
+ },
+ "Autosense": null,
+ "AdministrativeState": null,
+ "PortType": null,
+ "NeighborInfo": {
+ "CableId": null,
+ "SwitchId": null,
+ "PortId": null
+ }
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/index.json
new file mode 100644
index 0000000..0353960
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/Ports/index.json
@@ -0,0 +1,70 @@
+{
+ "@odata.type": "#EthernetSwitchPortCollection.EthernetSwitchPortCollection",
+ "Name": "Ethernet Switch Port Collection",
+ "@odata.context": "/redfish/v1/$metadata#EthernetSwitchPortCollection.EthernetSwitchPortCollection",
+ "Members": [
+ {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/1"
+ },
+ {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/2"
+ },
+ {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/3"
+ },
+ {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/4"
+ },
+ {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/5"
+ },
+ {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/6"
+ },
+ {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/7"
+ },
+ {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/8"
+ },
+ {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/9"
+ },
+ {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/10"
+ },
+ {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/11"
+ },
+ {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/12"
+ },
+ {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/13"
+ },
+ {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/14"
+ },
+ {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/15"
+ },
+ {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/16"
+ },
+ {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/17"
+ },
+ {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/18"
+ },
+ {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/19"
+ },
+ {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports/20"
+ }
+ ],
+ "Description": "Collection of Ethernet Switch Ports",
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports",
+ "Members@odata.count": 20
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/index.json
new file mode 100644
index 0000000..5d44735
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/1/index.json
@@ -0,0 +1,39 @@
+{
+ "SerialNumber": null,
+ "FirmwareName": null,
+ "Model": null,
+ "Name": "Switch1",
+ "Links": {
+ "ManagedBy": [
+ {
+ "@odata.id": "/redfish/v1/Managers/1"
+ }
+ ],
+ "Chassis": {
+ "@odata.id": "/redfish/v1/Chassis/1"
+ }
+ },
+ "Role": "TOR",
+ "MaxACLNumber": 10,
+ "Id": "1",
+ "FirmwareVersion": null,
+ "Description": "Ethernet Switch description",
+ "SwitchId": null,
+ "ACLs": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/ACLs"
+ },
+ "ManufacturingDate": null,
+ "Ports": {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1/Ports"
+ },
+ "@odata.type": "#EthernetSwitch.v1_0_0.EthernetSwitch",
+ "@odata.context": "/redfish/v1/$metadata#EthernetSwitch.EthernetSwitch",
+ "Status": {
+ "State": "Enabled",
+ "HealthRollup": "OK",
+ "Health": "OK"
+ },
+ "Manufacturer": null,
+ "@odata.id": "/redfish/v1/EthernetSwitches/1",
+ "PartNumber": null
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/index.json b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/index.json
new file mode 100644
index 0000000..db51199
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EthernetSwitches/index.json
@@ -0,0 +1,13 @@
+{
+ "@odata.type": "#EthernetSwitchCollection.EthernetSwitchCollection",
+ "Name": "Ethernet Switches Collection",
+ "@odata.context": "/redfish/v1/$metadata#EthernetSwitchCollection.EthernetSwitchCollection",
+ "Members": [
+ {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1"
+ }
+ ],
+ "Description": "Collection of Ethernet Switches",
+ "@odata.id": "/redfish/v1/EthernetSwitches",
+ "Members@odata.count": 1
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EventService/Subscriptions/index.json b/mock-redfish-server/mockup/redfish/v1/EventService/Subscriptions/index.json
new file mode 100644
index 0000000..b16ab33
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EventService/Subscriptions/index.json
@@ -0,0 +1,9 @@
+{
+ "@odata.type": "#EventDestinationCollection.EventDestinationCollection",
+ "Name": "Event Subscriptions Collection",
+ "@odata.context": "/redfish/v1/$metadata#EventService.EventService",
+ "Members": [],
+ "Description": "Collection of Event Subscriptions",
+ "@odata.id": "/redfish/v1/EventService/Subscriptions",
+ "Members@odata.count": 0
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/EventService/index.json b/mock-redfish-server/mockup/redfish/v1/EventService/index.json
new file mode 100644
index 0000000..c322976
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/EventService/index.json
@@ -0,0 +1,28 @@
+{
+ "ServiceEnabled": true,
+ "Name": "Event Service",
+ "Id": "EventService",
+ "Subscriptions": {
+ "@odata.id": "/redfish/v1/EventService/Subscriptions"
+ },
+ "Description": "Event Service description",
+ "Actions": {
+ "Oem": {}
+ },
+ "DeliveryRetryIntervalSeconds": 60,
+ "@odata.type": "#EventService.v1_0_0.EventService",
+ "@odata.context": "/redfish/v1/$metadata#EventService.EventService",
+ "Status": {
+ "State": "Enabled",
+ "HealthRollup": "OK",
+ "Health": "OK"
+ },
+ "DeliveryRetryAttempts": 3,
+ "@odata.id": "/redfish/v1/EventService",
+ "Oem": {},
+ "EventTypesForSubscription": [
+ "ResourceAdded",
+ "ResourceRemoved",
+ "Alert"
+ ]
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/Managers/1/EthernetInterfaces/1/index.json b/mock-redfish-server/mockup/redfish/v1/Managers/1/EthernetInterfaces/1/index.json
new file mode 100644
index 0000000..e355abc
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/Managers/1/EthernetInterfaces/1/index.json
@@ -0,0 +1,81 @@
+{
+ "FQDN": "localhost",
+ "IPv6StaticDefaultGateways": [],
+ "Name": "Manager NIC",
+ "MACAddress": "a8:2b:b5:36:78:6c",
+ "StatelessAddressAutoConfig": {
+ "IPv6AutoConfigEnabled": false
+ },
+ "MaxIPv6StaticAddresses": null,
+ "NameServers": [
+ "8.8.8.8"
+ ],
+ "IPv6DefaultGateway": "",
+ "HostName": "localhost",
+ "IPv4StaticAddresses": [
+ {
+ "Address": "10.90.0.114"
+ }
+ ],
+ "IPv6StaticAddresses": [],
+ "@odata.id": "/redfish/v1/Managers/1/EthernetInterfaces/1",
+ "SpeedMbps": 1000,
+ "Links": {
+ "Oem": {
+ "Intel_RackScale": {
+ "@odata.type": "#Intel.Oem.EthernetInterface"
+ }
+ },
+ "Endpoints": []
+ },
+ "Oem": {},
+ "InterfaceEnabled": true,
+ "IPv6Addresses": [
+ {
+ "PrefixLength": 64,
+ "AddressOrigin": "LinkLocal",
+ "Address": "fe80::aa2b:b5ff:fe36:786c",
+ "AddressState": null
+ }
+ ],
+ "MTUSize": 1500,
+ "StaticNameServers": [
+ "8.8.8.8"
+ ],
+ "LinkStatus": "LinkUp",
+ "Id": "1",
+ "PermanentMACAddress": "a8:2b:b5:36:78:6c",
+ "Description": "Manager NIC description",
+ "AutoNeg": true,
+ "IPv6AddressPolicyTable": [],
+ "IPv4Addresses": [
+ {
+ "AddressOrigin": "Static",
+ "Gateway": "10.90.0.1",
+ "Address": "10.90.0.114",
+ "SubnetMask": "255.255.0.0"
+ }
+ ],
+ "DHCPv6": {
+ "OperatingMode": "Disabled",
+ "UseDNSServers": false,
+ "UseRapidCommit": false,
+ "UseNTPServers": false
+ },
+ "@odata.type": "#EthernetInterface.v1_4_0.EthernetInterface",
+ "@odata.context": "/redfish/v1/$metadata#EthernetInterface.EthernetInterface",
+ "Status": {
+ "State": "Enabled",
+ "HealthRollup": "OK",
+ "Health": "OK"
+ },
+ "FullDuplex": true,
+ "DHCPv4": {
+ "UseDNSServers": true,
+ "DHCPEnabled": false,
+ "UseNTPServers": false,
+ "UseDomainName": false,
+ "UseGateway": true,
+ "UseStaticRoutes": false
+ }
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/Managers/1/EthernetInterfaces/index.json b/mock-redfish-server/mockup/redfish/v1/Managers/1/EthernetInterfaces/index.json
new file mode 100644
index 0000000..47106fd
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/Managers/1/EthernetInterfaces/index.json
@@ -0,0 +1,13 @@
+{
+ "@odata.type": "#EthernetInterfaceCollection.EthernetInterfaceCollection",
+ "Name": "Ethernet Network Interface Collection",
+ "@odata.context": "/redfish/v1/$metadata#EthernetInterfaceCollection.EthernetInterfaceCollection",
+ "Members": [
+ {
+ "@odata.id": "/redfish/v1/Managers/1/EthernetInterfaces/1"
+ }
+ ],
+ "Description": "a Collection of Manager Ethernet Interfaces",
+ "@odata.id": "/redfish/v1/Managers/1/EthernetInterfaces",
+ "Members@odata.count": 1
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/Managers/1/LogServices/1/Entries/index.json b/mock-redfish-server/mockup/redfish/v1/Managers/1/LogServices/1/Entries/index.json
new file mode 100644
index 0000000..9f99983
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/Managers/1/LogServices/1/Entries/index.json
@@ -0,0 +1,9 @@
+{
+ "@odata.type": "#LogEntryCollection.LogEntryCollection",
+ "Name": "Log Service Collection",
+ "@odata.context": "/redfish/v1/$metadata#LogEntryCollection.LogEntryCollection",
+ "Members": [],
+ "Description": "Collection of Logs for this System",
+ "@odata.id": "/redfish/v1/Managers/1/LogServices/1/Entries",
+ "Members@odata.count": 0
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/Managers/1/LogServices/1/index.json b/mock-redfish-server/mockup/redfish/v1/Managers/1/LogServices/1/index.json
new file mode 100644
index 0000000..17be88a
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/Managers/1/LogServices/1/index.json
@@ -0,0 +1,25 @@
+{
+ "DateTime": "2020-04-07T00:42:53+00:00",
+ "ServiceEnabled": false,
+ "Name": "System Log Service",
+ "DateTimeLocalOffset": "+00:00",
+ "Id": "1",
+ "Description": "ONL Peripheral Log",
+ "Actions": {
+ "#LogService.ClearLog": {
+ "target": "/redfish/v1/Managers/1/LogServices/1/Actions/LogService.Reset"
+ }
+ },
+ "MaxNumberOfRecords": 1000,
+ "Entries": {
+ "@odata.id": "/redfish/v1/Managers/1/LogServices/1/Entries"
+ },
+ "@odata.type": "#LogService.v1_0_0.LogService",
+ "@odata.context": "/redfish/v1/$metadata#LogService.LogService",
+ "Status": {
+ "State": "Enabled",
+ "Health": "OK"
+ },
+ "OverWritePolicy": "WrapsWhenFull",
+ "@odata.id": "/redfish/v1/Managers/1/LogServices/1"
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/Managers/1/LogServices/index.json b/mock-redfish-server/mockup/redfish/v1/Managers/1/LogServices/index.json
new file mode 100644
index 0000000..6d4cc47
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/Managers/1/LogServices/index.json
@@ -0,0 +1,13 @@
+{
+ "@odata.type": "#LogServiceCollection.LogServiceCollection",
+ "Name": "Log Service Collection",
+ "@odata.context": "/redfish/v1/$metadata##LogServiceCollection.LogServiceCollection",
+ "Members": [
+ {
+ "@odata.id": "/redfish/v1/Managers/1/LogServices/1"
+ }
+ ],
+ "Description": "Collection of Log Services for this Manager",
+ "@odata.id": "/redfish/v1/Managers/1/LogServices",
+ "Members@odata.count": 1
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/Managers/1/NetworkProtocol/index.json b/mock-redfish-server/mockup/redfish/v1/Managers/1/NetworkProtocol/index.json
new file mode 100644
index 0000000..817e576
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/Managers/1/NetworkProtocol/index.json
@@ -0,0 +1,55 @@
+{
+ "VirtualMedia": {
+ "ProtocolEnabled": null,
+ "Port": null
+ },
+ "FQDN": "localhost",
+ "SSDP": {
+ "NotifyTTL": 2,
+ "NotifyIPv6Scope": null,
+ "NotifyMulticastIntervalSeconds": 0,
+ "ProtocolEnabled": true,
+ "Port": 1900
+ },
+ "Name": "Manager Network Protocol",
+ "SNMP": {
+ "ProtocolEnabled": true,
+ "Port": 161
+ },
+ "IPMI": {
+ "ProtocolEnabled": null,
+ "Port": null
+ },
+ "Id": "NetworkProtocol",
+ "Description": "Manager Network Protocol description",
+ "KVMIP": {
+ "ProtocolEnabled": null,
+ "Port": null
+ },
+ "HTTP": {
+ "ProtocolEnabled": null,
+ "Port": null
+ },
+ "SSH": {
+ "ProtocolEnabled": true,
+ "Port": 22
+ },
+ "HostName": "localhost",
+ "HTTPS": {
+ "ProtocolEnabled": true,
+ "Port": 8888
+ },
+ "@odata.type": "#ManagerNetworkProtocol.v1_0_2.ManagerNetworkProtocol",
+ "Telnet": {
+ "ProtocolEnabled": null,
+ "Port": null
+ },
+ "@odata.context": "/redfish/v1/$metadata#ManagerNetworkProtocol.ManagerNetworkProtocol",
+ "Status": {
+ "State": "Enabled",
+ "HealthRollup": "OK",
+ "Health": "OK"
+ },
+ "@odata.id": "/redfish/v1/Managers/1/NetworkProtocol",
+ "Oem": {}
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/Managers/1/SerialInterfaces/1/index.json b/mock-redfish-server/mockup/redfish/v1/Managers/1/SerialInterfaces/1/index.json
new file mode 100644
index 0000000..83a1e9a
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/Managers/1/SerialInterfaces/1/index.json
@@ -0,0 +1,17 @@
+{
+ "FlowControl": "None",
+ "Name": "Manager Serial Interface",
+ "Parity": "None",
+ "Id": "1",
+ "DataBits": "8",
+ "Description": "Management for Serial Interface",
+ "PinOut": "Cyclades",
+ "BitRate": "115200",
+ "@odata.type": "#SerialInterface.v1_0_2.SerialInterface",
+ "@odata.context": "/redfish/v1/$metadata#SerialInterface.SerialInterface",
+ "StopBits": "1",
+ "@odata.id": "/redfish/v1/Managers/1/SerialInterfaces/1",
+ "SignalType": "Rs232",
+ "ConnectorType": "RJ45",
+ "InterfaceEnabled": true
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/Managers/1/SerialInterfaces/index.json b/mock-redfish-server/mockup/redfish/v1/Managers/1/SerialInterfaces/index.json
new file mode 100644
index 0000000..de489c4
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/Managers/1/SerialInterfaces/index.json
@@ -0,0 +1,13 @@
+{
+ "@odata.type": "#SerialInterfaceCollection.SerialInterfaceCollection",
+ "Name": "Serial Interface Collection",
+ "@odata.context": "/redfish/v1/$metadata#SerialInterfaceCollection.SerialInterfaceCollection",
+ "Members": [
+ {
+ "@odata.id": "/redfish/v1/Managers/1/SerialInterfaces/1"
+ }
+ ],
+ "Description": "a Collection of Serial Interfaces",
+ "@odata.id": "/redfish/v1/Managers/1/SerialInterfaces",
+ "Members@odata.count": 1
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/Managers/1/index.json b/mock-redfish-server/mockup/redfish/v1/Managers/1/index.json
new file mode 100644
index 0000000..8f18664
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/Managers/1/index.json
@@ -0,0 +1,62 @@
+{
+ "DateTime": "2020-04-07T00:42:37+00:00",
+ "Name": "Manager",
+ "Links": {
+ "Oem": {
+ "Intel_RackScale": {
+ "ManagerForServices": [],
+ "@odata.type": "#Intel.Oem.ManagerLinks",
+ "ManagerForSwitches": [
+ {
+ "@odata.id": "/redfish/v1/EthernetSwitches/1"
+ }
+ ]
+ }
+ },
+ "ManagerForServers": [
+ {
+ "@odata.id": "/redfish/v1/Systems/1"
+ }
+ ],
+ "ManagerForChassis": [
+ {
+ "@odata.id": "/redfish/v1/Chassis/1"
+ }
+ ],
+ "@odata.type": "#Manager.v1_0_0.Links"
+ },
+ "DateTimeLocalOffset": "+00:00",
+ "Id": "1",
+ "FirmwareVersion": "2.1.3.59.25",
+ "Description": "Manager description",
+ "Model": null,
+ "NetworkProtocol": {
+ "@odata.id": "/redfish/v1/Managers/1/NetworkProtocol"
+ },
+ "SerialConsole": {
+ "ConnectTypesSupported": [],
+ "ServiceEnabled": true,
+ "MaxConcurrentSessions": 0
+ },
+ "UUID": "d6fee3aa-785f-11ea-8e4b-af25952f929b",
+ "@odata.type": "#Manager.v1_0_0.Manager",
+ "@odata.context": "/redfish/v1/$metadata#Manager.Manager",
+ "Status": {
+ "State": "Enabled",
+ "HealthRollup": "OK",
+ "Health": "OK"
+ },
+ "EthernetInterfaces": {
+ "@odata.id": "/redfish/v1/Managers/1/EthernetInterfaces"
+ },
+ "ServiceEntryPointUUID": "d6fee3aa-785f-11ea-8e4b-af25952f929b",
+ "@odata.id": "/redfish/v1/Managers/1",
+ "Oem": {},
+ "SerialInterfaces": {
+ "@odata.id": "/redfish/v1/Managers/1/SerialInterfaces"
+ },
+ "LogServices": {
+ "@odata.id": "/redfish/v1/Managers/1/LogServices"
+ },
+ "ManagerType": "EnclosureManager"
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/Managers/index.json b/mock-redfish-server/mockup/redfish/v1/Managers/index.json
new file mode 100644
index 0000000..890098a
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/Managers/index.json
@@ -0,0 +1,13 @@
+{
+ "@odata.type": "#ManagerCollection.ManagerCollection",
+ "Name": "Manager Collection",
+ "@odata.context": "/redfish/v1/$metadata#ManagerCollection.ManagerCollection",
+ "Members": [
+ {
+ "@odata.id": "/redfish/v1/Managers/1"
+ }
+ ],
+ "Description": "Collection of Managers",
+ "@odata.id": "/redfish/v1/Managers",
+ "Members@odata.count": 1
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/Registries/1/index.json b/mock-redfish-server/mockup/redfish/v1/Registries/1/index.json
new file mode 100644
index 0000000..0138832
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/Registries/1/index.json
@@ -0,0 +1,19 @@
+{
+ "Languages": [
+ "en"
+ ],
+ "Registry": "Base.1.0",
+ "@odata.type": "#MessageRegistryFile.v1_0_0.MessageRegistryFile",
+ "Name": "Base Message Registry File",
+ "@odata.context": "/redfish/v1/$metadata#MessageRegistryFile.MessageRegistryFile",
+ "Id": "1",
+ "Location": [
+ {
+ "Language": "en",
+ "PublicationUri": "https://www.dmtf.org/sites/default/files/standards/documents/DSP8011_1.0.0a.json"
+ }
+ ],
+ "Description": "Base Message Registry File locations",
+ "@odata.id": "/redfish/v1/Registries/1",
+ "Oem": {}
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/Registries/index.json b/mock-redfish-server/mockup/redfish/v1/Registries/index.json
new file mode 100644
index 0000000..e60abe3
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/Registries/index.json
@@ -0,0 +1,13 @@
+{
+ "@odata.type": "#MessageRegistryFileCollection.MessageRegistryFileCollection",
+ "Name": "MessageRegistryFile collection",
+ "@odata.context": "/redfish/v1/$metadata#MessageRegistryFileCollection.MessageRegistryFileCollection",
+ "Members": [
+ {
+ "@odata.id": "/redfish/v1/Registries/1"
+ }
+ ],
+ "Description": "Collection of Message Registry Files",
+ "@odata.id": "/redfish/v1/Registries",
+ "Members@odata.count": 1
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/SessionService/Sessions/index.json b/mock-redfish-server/mockup/redfish/v1/SessionService/Sessions/index.json
new file mode 100644
index 0000000..2fd3d6c
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/SessionService/Sessions/index.json
@@ -0,0 +1,9 @@
+{
+ "@odata.type": "#SessionCollection.SessionCollection",
+ "Name": "Session Collection",
+ "@odata.context": "/redfish/v1/$metadata#SessionCollection.SessionCollection",
+ "Members": [],
+ "Description": "Session Collection",
+ "@odata.id": "/redfish/v1/SessionService/Sessions",
+ "Members@odata.count": 0
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/SessionService/index.json b/mock-redfish-server/mockup/redfish/v1/SessionService/index.json
new file mode 100644
index 0000000..780ea96
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/SessionService/index.json
@@ -0,0 +1,19 @@
+{
+ "ServiceEnabled": false,
+ "SessionTimeout": 300,
+ "@odata.type": "#SessionService.v1_0_0.SessionService",
+ "Name": "Session Service",
+ "@odata.context": "/redfish/v1/$metadata#SessionService.SessionService",
+ "Status": {
+ "State": "Enabled",
+ "HealthRollup": "OK",
+ "Health": "OK"
+ },
+ "Id": "SessionService",
+ "Description": "Session Service ",
+ "@odata.id": "/redfish/v1/SessionService",
+ "Oem": {},
+ "Sessions": {
+ "@odata.id": "/redfish/v1/SessionService/Sessions"
+ }
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/Systems/1/Memory/1/index.json b/mock-redfish-server/mockup/redfish/v1/Systems/1/Memory/1/index.json
new file mode 100644
index 0000000..5cd34b2
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/Systems/1/Memory/1/index.json
@@ -0,0 +1,52 @@
+{
+ "SerialNumber": null,
+ "Name": "Memory",
+ "FirmwareApiVersion": null,
+ "MemoryMedia": [],
+ "Manufacturer": null,
+ "DeviceLocator": "DIMM_A1",
+ "BaseModuleType": null,
+ "CapacityMiB": 7812,
+ "FunctionClasses": [],
+ "Regions": [
+ {
+ "MemoryClassification": null,
+ "SizeMiB": 7812,
+ "OffsetMiB": 0,
+ "RegionId": "1"
+ }
+ ],
+ "@odata.id": "/redfish/v1/Systems/1/Memory/1",
+ "OperatingSpeedMhz": 2133,
+ "ErrorCorrection": null,
+ "OperatingMemoryModes": [],
+ "Status": {
+ "State": "Enabled",
+ "HealthRollup": "OK",
+ "Health": "OK"
+ },
+ "BusWidthBits": null,
+ "RankCount": null,
+ "Oem": {
+ "Intel_RackScale": {
+ "VoltageVolt": null,
+ "@odata.type": "#Intel.Oem.Memory"
+ }
+ },
+ "Id": "1",
+ "Description": "Memory description",
+ "MemoryDeviceType": "DDR3_SDRAM",
+ "@odata.type": "#Memory.v1_1_0.Memory",
+ "DataWidthBits": 64,
+ "@odata.context": "/redfish/v1/$metadata#Memory.Memory",
+ "MemoryType": null,
+ "FirmwareRevision": null,
+ "AllowedSpeedsMHz": [],
+ "MemoryLocation": {
+ "Socket": null,
+ "MemoryController": null,
+ "Slot": null,
+ "Channel": null
+ },
+ "PartNumber": null
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/Systems/1/Memory/2/index.json b/mock-redfish-server/mockup/redfish/v1/Systems/1/Memory/2/index.json
new file mode 100644
index 0000000..61ad245
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/Systems/1/Memory/2/index.json
@@ -0,0 +1,52 @@
+{
+ "SerialNumber": null,
+ "Name": "Memory",
+ "FirmwareApiVersion": null,
+ "MemoryMedia": [],
+ "Manufacturer": null,
+ "DeviceLocator": "DIMM_B1",
+ "BaseModuleType": null,
+ "CapacityMiB": 7812,
+ "FunctionClasses": [],
+ "Regions": [
+ {
+ "MemoryClassification": null,
+ "SizeMiB": 7812,
+ "OffsetMiB": 0,
+ "RegionId": "2"
+ }
+ ],
+ "@odata.id": "/redfish/v1/Systems/1/Memory/2",
+ "OperatingSpeedMhz": 2133,
+ "ErrorCorrection": null,
+ "OperatingMemoryModes": [],
+ "Status": {
+ "State": "Enabled",
+ "HealthRollup": "OK",
+ "Health": "OK"
+ },
+ "BusWidthBits": null,
+ "RankCount": null,
+ "Oem": {
+ "Intel_RackScale": {
+ "VoltageVolt": null,
+ "@odata.type": "#Intel.Oem.Memory"
+ }
+ },
+ "Id": "2",
+ "Description": "Memory description",
+ "MemoryDeviceType": "DDR3_SDRAM",
+ "@odata.type": "#Memory.v1_1_0.Memory",
+ "DataWidthBits": 64,
+ "@odata.context": "/redfish/v1/$metadata#Memory.Memory",
+ "MemoryType": null,
+ "FirmwareRevision": null,
+ "AllowedSpeedsMHz": [],
+ "MemoryLocation": {
+ "Socket": null,
+ "MemoryController": null,
+ "Slot": null,
+ "Channel": null
+ },
+ "PartNumber": null
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/Systems/1/Memory/index.json b/mock-redfish-server/mockup/redfish/v1/Systems/1/Memory/index.json
new file mode 100644
index 0000000..e2631a0
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/Systems/1/Memory/index.json
@@ -0,0 +1,16 @@
+{
+ "@odata.type": "#MemoryCollection.MemoryCollection",
+ "Name": "Memory Collection",
+ "@odata.context": "/redfish/v1/$metadata#MemoryCollection.MemoryCollection",
+ "Members": [
+ {
+ "@odata.id": "/redfish/v1/Systems/1/Memory/1"
+ },
+ {
+ "@odata.id": "/redfish/v1/Systems/1/Memory/2"
+ }
+ ],
+ "Description": "Memory Collection",
+ "@odata.id": "/redfish/v1/Systems/1/Memory",
+ "Members@odata.count": 2
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/Systems/1/Processors/1/index.json b/mock-redfish-server/mockup/redfish/v1/Systems/1/Processors/1/index.json
new file mode 100644
index 0000000..947d557
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/Systems/1/Processors/1/index.json
@@ -0,0 +1,50 @@
+{
+ "ProcessorId": {
+ "IdentificationRegisters": null,
+ "VendorId": "GenuineIntel",
+ "EffectiveModel": null,
+ "EffectiveFamily": null,
+ "MicrocodeInfo": null,
+ "Step": null
+ },
+ "Model": "Intel(R) Xeon(R) CPU D-1518 @ 2.20GHz",
+ "Name": "Processor",
+ "TotalThreads": 2,
+ "TotalCores": 4,
+ "ProcessorArchitecture": "x86",
+ "Description": "Processor Description",
+ "Id": "1",
+ "MaxSpeedMHz": 800,
+ "Socket": "CPU0",
+ "ProcessorType": "CPU",
+ "@odata.type": "#Processor.v1_0_0.Processor",
+ "@odata.context": "/redfish/v1/$metadata#Processor.Processor",
+ "Status": {
+ "State": "Enabled",
+ "HealthRollup": "OK",
+ "Health": "OK"
+ },
+ "Manufacturer": "Intel Corporation",
+ "@odata.id": "/redfish/v1/Systems/1/Processors/1",
+ "Oem": {
+ "Intel_RackScale": {
+ "Capabilities": [],
+ "@odata.type": "#Intel.Oem.Processor",
+ "Brand": "Unknown"
+ }
+ },
+ "InstructionSet": "x86-64",
+ "CpuStatus": {
+ "io wait": 0,
+ "guest": 0,
+ "LoadingPercentage": 0.6329113841056824,
+ "guest nice": 0,
+ "system": 0.6320000290870667,
+ "user nice": 0,
+ "soft irq": 0,
+ "user": 0,
+ "steal": 0,
+ "idle": 99.36699676513672,
+ "hard irq": 0
+ }
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/Systems/1/Processors/index.json b/mock-redfish-server/mockup/redfish/v1/Systems/1/Processors/index.json
new file mode 100644
index 0000000..99a68ea
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/Systems/1/Processors/index.json
@@ -0,0 +1,13 @@
+{
+ "@odata.type": "#ProcessorCollection.ProcessorCollection",
+ "Name": "Processor Collection",
+ "@odata.context": "/redfish/v1/$metadata#ProcessorCollection.ProcessorCollection",
+ "Members": [
+ {
+ "@odata.id": "/redfish/v1/Systems/1/Processors/1"
+ }
+ ],
+ "Description": "Collection of Processors",
+ "@odata.id": "/redfish/v1/Systems/1/Processors",
+ "Members@odata.count": 1
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/Systems/1/Storage/1/Volumes/index.json b/mock-redfish-server/mockup/redfish/v1/Systems/1/Storage/1/Volumes/index.json
new file mode 100644
index 0000000..541c298
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/Systems/1/Storage/1/Volumes/index.json
@@ -0,0 +1,9 @@
+{
+ "@odata.type": "#VolumeCollection.VolumeCollection",
+ "Name": "Computer Volume Collection",
+ "@odata.context": "/redfish/v1/$metadata#VolumeCollection.VolumeCollection",
+ "Members": [],
+ "Description": "Computer Volume Collection",
+ "@odata.id": "/redfish/v1/Systems/1/Storage/1/Volumes",
+ "Members@odata.count": 0
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/Systems/1/Storage/1/index.json b/mock-redfish-server/mockup/redfish/v1/Systems/1/Storage/1/index.json
new file mode 100644
index 0000000..b0d96f6
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/Systems/1/Storage/1/index.json
@@ -0,0 +1,24 @@
+{
+ "Name": "Storage Subsystem",
+ "Links": {},
+ "Status": {
+ "State": "Enabled",
+ "HealthRollup": "OK",
+ "Health": "OK"
+ },
+ "Volumes": {
+ "@odata.id": "/redfish/v1/Systems/1/Storage/1/Volumes"
+ },
+ "Id": "1",
+ "Description": "Storage Subsystem description",
+ "Actions": {},
+ "@odata.type": "#Storage.v1_1_0.Storage",
+ "@odata.context": "/redfish/v1/$metadata#Storage.Storage",
+ "StorageControllers": [],
+ "@odata.id": "/redfish/v1/Systems/1/Storage/1",
+ "Drives": [
+ {
+ "@odata.id": "/redfish/v1/Chassis/1/Drives/1"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/Systems/1/Storage/index.json b/mock-redfish-server/mockup/redfish/v1/Systems/1/Storage/index.json
new file mode 100644
index 0000000..9a6f9bf
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/Systems/1/Storage/index.json
@@ -0,0 +1,12 @@
+{
+ "@odata.type": "#StorageCollection.StorageCollection",
+ "Name": "Storage Collection",
+ "@odata.context": "/redfish/v1/$metadata#StorageCollection.StorageCollection",
+ "Members": [
+ {
+ "@odata.id": "/redfish/v1/Systems/1/Storage/1"
+ }
+ ],
+ "@odata.id": "/redfish/v1/Systems/1/Storage",
+ "Members@odata.count": 1
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/Systems/1/index.json b/mock-redfish-server/mockup/redfish/v1/Systems/1/index.json
new file mode 100644
index 0000000..903a409
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/Systems/1/index.json
@@ -0,0 +1,100 @@
+{
+ "SerialNumber": "EC1721000216",
+ "BiosVersion": "5.11",
+ "Name": "Computer System",
+ "IndicatorLED": "Lit",
+ "Manufacturer": "Accton",
+ "Memory": {
+ "@odata.id": "/redfish/v1/Systems/1/Memory"
+ },
+ "HostName": "localhost",
+ "Storage": {
+ "@odata.id": "/redfish/v1/Systems/1/Storage"
+ },
+ "PCIeFunctions": [],
+ "UUID": "d6fee3aa-785f-11ea-8e4b-af25952f929b",
+ "@odata.id": "/redfish/v1/Systems/1",
+ "AssetTag": "N/A",
+ "SystemType": "Physical",
+ "Oem": {
+ "Intel_RackScale": {
+ "ProcessorSockets": 1,
+ "DiscoveryState": "Basic",
+ "@odata.type": "#Intel.Oem.ComputerSystem",
+ "PCIeConnectionId": [],
+ "MemorySockets": 2,
+ "PciDevices": []
+ }
+ },
+ "Boot": {
+ "BootSourceOverrideMode": "Legacy",
+ "BootSourceOverrideTarget": "None",
+ "BootSourceOverrideEnabled": "Disabled"
+ },
+ "MemoryState": {
+ "FreeSwapMemoryByte": 0,
+ "TotalSwapMemoryByte": 0,
+ "FreeMemoryByte": 16169037824,
+ "TotalMemoryByte": 16687493120
+ },
+ "ProcessorSummary": {
+ "Model": "Intel(R) Xeon(R) CPU D-1518 @ 2.20GHz",
+ "Count": 1,
+ "Status": {
+ "State": "Enabled",
+ "HealthRollup": "OK",
+ "Health": "OK"
+ }
+ },
+ "PCIeDevices": [],
+ "Links": {
+ "Oem": {},
+ "ManagedBy": [
+ {
+ "@odata.id": "/redfish/v1/Managers/1"
+ }
+ ],
+ "@odata.type": "#ComputerSystem.v1_2_0.Links",
+ "Endpoints": [],
+ "Chassis": [
+ {
+ "@odata.id": "/redfish/v1/Chassis/1"
+ }
+ ]
+ },
+ "Id": "1",
+ "Description": "Computer System description",
+ "Model": "",
+ "PowerState": "On",
+ "Actions": {
+ "#ComputerSystem.Reset": {
+ "target": "/redfish/v1/Systems/1/Actions/ComputerSystem.Reset",
+ "ResetType@Redfish.AllowableValues": [
+ "ForceOff",
+ "GracefulShutdown",
+ "GracefulRestart",
+ "ForceRestart"
+ ]
+ }
+ },
+ "@odata.type": "#ComputerSystem.v1_3_0.ComputerSystem",
+ "SKU": null,
+ "@odata.context": "/redfish/v1/$metadata#ComputerSystem.ComputerSystem",
+ "Status": {
+ "State": "Enabled",
+ "HealthRollup": "OK",
+ "Health": "OK"
+ },
+ "Processors": {
+ "@odata.id": "/redfish/v1/Systems/1/Processors"
+ },
+ "MemorySummary": {
+ "TotalSystemMemoryGiB": 15.26,
+ "Status": {
+ "State": "Enabled",
+ "HealthRollup": "OK",
+ "Health": "OK"
+ }
+ },
+ "PartNumber": ""
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/Systems/index.json b/mock-redfish-server/mockup/redfish/v1/Systems/index.json
new file mode 100644
index 0000000..112e0ed
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/Systems/index.json
@@ -0,0 +1,13 @@
+{
+ "@odata.type": "#ComputerSystemCollection.ComputerSystemCollection",
+ "Name": "Computer System Collection",
+ "@odata.context": "/redfish/v1/$metadata#ComputerSystemCollection.ComputerSystemCollection",
+ "Members": [
+ {
+ "@odata.id": "/redfish/v1/Systems/1"
+ }
+ ],
+ "Description": "Collection of Computer Systems",
+ "@odata.id": "/redfish/v1/Systems",
+ "Members@odata.count": 1
+}
\ No newline at end of file
diff --git a/mock-redfish-server/mockup/redfish/v1/index.json b/mock-redfish-server/mockup/redfish/v1/index.json
new file mode 100644
index 0000000..ec747fa
--- /dev/null
+++ b/mock-redfish-server/mockup/redfish/v1/index.json
@@ -0,0 +1 @@
+null
\ No newline at end of file
diff --git a/vendor/github.com/jessevdk/go-flags/.travis.yml b/vendor/github.com/jessevdk/go-flags/.travis.yml
new file mode 100644
index 0000000..0f0728d
--- /dev/null
+++ b/vendor/github.com/jessevdk/go-flags/.travis.yml
@@ -0,0 +1,44 @@
+language: go
+
+os:
+ - linux
+ - osx
+
+go:
+ - 1.x
+ - 1.7.x
+ - 1.8.x
+ - 1.9.x
+ - 1.10.x
+
+install:
+ # go-flags
+ - go get -d -v ./...
+ - go build -v ./...
+
+ # linting
+ - go get github.com/golang/lint/golint
+
+ # code coverage
+ - go get golang.org/x/tools/cmd/cover
+ - go get github.com/onsi/ginkgo/ginkgo
+ - go get github.com/modocache/gover
+ - if [ "$TRAVIS_SECURE_ENV_VARS" = "true" ]; then go get github.com/mattn/goveralls; fi
+
+script:
+ # go-flags
+ - $(exit $(gofmt -l . | wc -l))
+ - go test -v ./...
+
+ # linting
+ - go tool vet -all=true -v=true . || true
+ - $(go env GOPATH | awk 'BEGIN{FS=":"} {print $1}')/bin/golint ./...
+
+ # code coverage
+ - $(go env GOPATH | awk 'BEGIN{FS=":"} {print $1}')/bin/ginkgo -r -cover
+ - $(go env GOPATH | awk 'BEGIN{FS=":"} {print $1}')/bin/gover
+ - if [ "$TRAVIS_SECURE_ENV_VARS" = "true" ]; then $(go env GOPATH | awk 'BEGIN{FS=":"} {print $1}')/bin/goveralls -coverprofile=gover.coverprofile -service=travis-ci -repotoken $COVERALLS_TOKEN; fi
+
+env:
+ # coveralls.io
+ secure: "RCYbiB4P0RjQRIoUx/vG/AjP3mmYCbzOmr86DCww1Z88yNcy3hYr3Cq8rpPtYU5v0g7wTpu4adaKIcqRE9xknYGbqj3YWZiCoBP1/n4Z+9sHW3Dsd9D/GRGeHUus0laJUGARjWoCTvoEtOgTdGQDoX7mH+pUUY0FBltNYUdOiiU="
diff --git a/vendor/github.com/jessevdk/go-flags/LICENSE b/vendor/github.com/jessevdk/go-flags/LICENSE
new file mode 100644
index 0000000..bcca0d5
--- /dev/null
+++ b/vendor/github.com/jessevdk/go-flags/LICENSE
@@ -0,0 +1,26 @@
+Copyright (c) 2012 Jesse van den Kieboom. 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/jessevdk/go-flags/README.md b/vendor/github.com/jessevdk/go-flags/README.md
new file mode 100644
index 0000000..3b02394
--- /dev/null
+++ b/vendor/github.com/jessevdk/go-flags/README.md
@@ -0,0 +1,134 @@
+go-flags: a go library for parsing command line arguments
+=========================================================
+
+[![GoDoc](https://godoc.org/github.com/jessevdk/go-flags?status.png)](https://godoc.org/github.com/jessevdk/go-flags) [![Build Status](https://travis-ci.org/jessevdk/go-flags.svg?branch=master)](https://travis-ci.org/jessevdk/go-flags) [![Coverage Status](https://img.shields.io/coveralls/jessevdk/go-flags.svg)](https://coveralls.io/r/jessevdk/go-flags?branch=master)
+
+This library provides similar functionality to the builtin flag library of
+go, but provides much more functionality and nicer formatting. From the
+documentation:
+
+Package flags provides an extensive command line option parser.
+The flags package is similar in functionality to the go builtin flag package
+but provides more options and uses reflection to provide a convenient and
+succinct way of specifying command line options.
+
+Supported features:
+* Options with short names (-v)
+* Options with long names (--verbose)
+* Options with and without arguments (bool v.s. other type)
+* Options with optional arguments and default values
+* Multiple option groups each containing a set of options
+* Generate and print well-formatted help message
+* Passing remaining command line arguments after -- (optional)
+* Ignoring unknown command line options (optional)
+* Supports -I/usr/include -I=/usr/include -I /usr/include option argument specification
+* Supports multiple short options -aux
+* Supports all primitive go types (string, int{8..64}, uint{8..64}, float)
+* Supports same option multiple times (can store in slice or last option counts)
+* Supports maps
+* Supports function callbacks
+* Supports namespaces for (nested) option groups
+
+The flags package uses structs, reflection and struct field tags
+to allow users to specify command line options. This results in very simple
+and concise specification of your application options. For example:
+
+```go
+type Options struct {
+ Verbose []bool `short:"v" long:"verbose" description:"Show verbose debug information"`
+}
+```
+
+This specifies one option with a short name -v and a long name --verbose.
+When either -v or --verbose is found on the command line, a 'true' value
+will be appended to the Verbose field. e.g. when specifying -vvv, the
+resulting value of Verbose will be {[true, true, true]}.
+
+Example:
+--------
+```go
+var opts struct {
+ // Slice of bool will append 'true' each time the option
+ // is encountered (can be set multiple times, like -vvv)
+ Verbose []bool `short:"v" long:"verbose" description:"Show verbose debug information"`
+
+ // Example of automatic marshalling to desired type (uint)
+ Offset uint `long:"offset" description:"Offset"`
+
+ // Example of a callback, called each time the option is found.
+ Call func(string) `short:"c" description:"Call phone number"`
+
+ // Example of a required flag
+ Name string `short:"n" long:"name" description:"A name" required:"true"`
+
+ // Example of a value name
+ File string `short:"f" long:"file" description:"A file" value-name:"FILE"`
+
+ // Example of a pointer
+ Ptr *int `short:"p" description:"A pointer to an integer"`
+
+ // Example of a slice of strings
+ StringSlice []string `short:"s" description:"A slice of strings"`
+
+ // Example of a slice of pointers
+ PtrSlice []*string `long:"ptrslice" description:"A slice of pointers to string"`
+
+ // Example of a map
+ IntMap map[string]int `long:"intmap" description:"A map from string to int"`
+}
+
+// Callback which will invoke callto:<argument> to call a number.
+// Note that this works just on OS X (and probably only with
+// Skype) but it shows the idea.
+opts.Call = func(num string) {
+ cmd := exec.Command("open", "callto:"+num)
+ cmd.Start()
+ cmd.Process.Release()
+}
+
+// Make some fake arguments to parse.
+args := []string{
+ "-vv",
+ "--offset=5",
+ "-n", "Me",
+ "-p", "3",
+ "-s", "hello",
+ "-s", "world",
+ "--ptrslice", "hello",
+ "--ptrslice", "world",
+ "--intmap", "a:1",
+ "--intmap", "b:5",
+ "arg1",
+ "arg2",
+ "arg3",
+}
+
+// Parse flags from `args'. Note that here we use flags.ParseArgs for
+// the sake of making a working example. Normally, you would simply use
+// flags.Parse(&opts) which uses os.Args
+args, err := flags.ParseArgs(&opts, args)
+
+if err != nil {
+ panic(err)
+}
+
+fmt.Printf("Verbosity: %v\n", opts.Verbose)
+fmt.Printf("Offset: %d\n", opts.Offset)
+fmt.Printf("Name: %s\n", opts.Name)
+fmt.Printf("Ptr: %d\n", *opts.Ptr)
+fmt.Printf("StringSlice: %v\n", opts.StringSlice)
+fmt.Printf("PtrSlice: [%v %v]\n", *opts.PtrSlice[0], *opts.PtrSlice[1])
+fmt.Printf("IntMap: [a:%v b:%v]\n", opts.IntMap["a"], opts.IntMap["b"])
+fmt.Printf("Remaining args: %s\n", strings.Join(args, " "))
+
+// Output: Verbosity: [true true]
+// Offset: 5
+// Name: Me
+// Ptr: 3
+// StringSlice: [hello world]
+// PtrSlice: [hello world]
+// IntMap: [a:1 b:5]
+// Remaining args: arg1 arg2 arg3
+```
+
+More information can be found in the godocs: <http://godoc.org/github.com/jessevdk/go-flags>
diff --git a/vendor/github.com/jessevdk/go-flags/arg.go b/vendor/github.com/jessevdk/go-flags/arg.go
new file mode 100644
index 0000000..8ec6204
--- /dev/null
+++ b/vendor/github.com/jessevdk/go-flags/arg.go
@@ -0,0 +1,27 @@
+package flags
+
+import (
+ "reflect"
+)
+
+// Arg represents a positional argument on the command line.
+type Arg struct {
+ // The name of the positional argument (used in the help)
+ Name string
+
+ // A description of the positional argument (used in the help)
+ Description string
+
+ // The minimal number of required positional arguments
+ Required int
+
+ // The maximum number of required positional arguments
+ RequiredMaximum int
+
+ value reflect.Value
+ tag multiTag
+}
+
+func (a *Arg) isRemaining() bool {
+ return a.value.Type().Kind() == reflect.Slice
+}
diff --git a/vendor/github.com/jessevdk/go-flags/check_crosscompile.sh b/vendor/github.com/jessevdk/go-flags/check_crosscompile.sh
new file mode 100644
index 0000000..c494f61
--- /dev/null
+++ b/vendor/github.com/jessevdk/go-flags/check_crosscompile.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+set -e
+
+echo '# linux arm7'
+GOARM=7 GOARCH=arm GOOS=linux go build
+echo '# linux arm5'
+GOARM=5 GOARCH=arm GOOS=linux go build
+echo '# windows 386'
+GOARCH=386 GOOS=windows go build
+echo '# windows amd64'
+GOARCH=amd64 GOOS=windows go build
+echo '# darwin'
+GOARCH=amd64 GOOS=darwin go build
+echo '# freebsd'
+GOARCH=amd64 GOOS=freebsd go build
diff --git a/vendor/github.com/jessevdk/go-flags/closest.go b/vendor/github.com/jessevdk/go-flags/closest.go
new file mode 100644
index 0000000..3b51875
--- /dev/null
+++ b/vendor/github.com/jessevdk/go-flags/closest.go
@@ -0,0 +1,59 @@
+package flags
+
+func levenshtein(s string, t string) int {
+ if len(s) == 0 {
+ return len(t)
+ }
+
+ if len(t) == 0 {
+ return len(s)
+ }
+
+ dists := make([][]int, len(s)+1)
+ for i := range dists {
+ dists[i] = make([]int, len(t)+1)
+ dists[i][0] = i
+ }
+
+ for j := range t {
+ dists[0][j] = j
+ }
+
+ for i, sc := range s {
+ for j, tc := range t {
+ if sc == tc {
+ dists[i+1][j+1] = dists[i][j]
+ } else {
+ dists[i+1][j+1] = dists[i][j] + 1
+ if dists[i+1][j] < dists[i+1][j+1] {
+ dists[i+1][j+1] = dists[i+1][j] + 1
+ }
+ if dists[i][j+1] < dists[i+1][j+1] {
+ dists[i+1][j+1] = dists[i][j+1] + 1
+ }
+ }
+ }
+ }
+
+ return dists[len(s)][len(t)]
+}
+
+func closestChoice(cmd string, choices []string) (string, int) {
+ if len(choices) == 0 {
+ return "", 0
+ }
+
+ mincmd := -1
+ mindist := -1
+
+ for i, c := range choices {
+ l := levenshtein(cmd, c)
+
+ if mincmd < 0 || l < mindist {
+ mindist = l
+ mincmd = i
+ }
+ }
+
+ return choices[mincmd], mindist
+}
diff --git a/vendor/github.com/jessevdk/go-flags/command.go b/vendor/github.com/jessevdk/go-flags/command.go
new file mode 100644
index 0000000..486bacb
--- /dev/null
+++ b/vendor/github.com/jessevdk/go-flags/command.go
@@ -0,0 +1,465 @@
+package flags
+
+import (
+ "reflect"
+ "sort"
+ "strconv"
+ "strings"
+)
+
+// Command represents an application command. Commands can be added to the
+// parser (which itself is a command) and are selected/executed when its name
+// is specified on the command line. The Command type embeds a Group and
+// therefore also carries a set of command specific options.
+type Command struct {
+ // Embedded, see Group for more information
+ *Group
+
+ // The name by which the command can be invoked
+ Name string
+
+ // The active sub command (set by parsing) or nil
+ Active *Command
+
+ // Whether subcommands are optional
+ SubcommandsOptional bool
+
+ // Aliases for the command
+ Aliases []string
+
+ // Whether positional arguments are required
+ ArgsRequired bool
+
+ commands []*Command
+ hasBuiltinHelpGroup bool
+ args []*Arg
+}
+
+// Commander is an interface which can be implemented by any command added in
+// the options. When implemented, the Execute method will be called for the last
+// specified (sub)command providing the remaining command line arguments.
+type Commander interface {
+ // Execute will be called for the last active (sub)command. The
+ // args argument contains the remaining command line arguments. The
+ // error that Execute returns will be eventually passed out of the
+ // Parse method of the Parser.
+ Execute(args []string) error
+}
+
+// Usage is an interface which can be implemented to show a custom usage string
+// in the help message shown for a command.
+type Usage interface {
+ // Usage is called for commands to allow customized printing of command
+ // usage in the generated help message.
+ Usage() string
+}
+
+type lookup struct {
+ shortNames map[string]*Option
+ longNames map[string]*Option
+
+ commands map[string]*Command
+}
+
+// AddCommand adds a new command to the parser with the given name and data. The
+// data needs to be a pointer to a struct from which the fields indicate which
+// options are in the command. The provided data can implement the Command and
+// Usage interfaces.
+func (c *Command) AddCommand(command string, shortDescription string, longDescription string, data interface{}) (*Command, error) {
+ cmd := newCommand(command, shortDescription, longDescription, data)
+
+ cmd.parent = c
+
+ if err := cmd.scan(); err != nil {
+ return nil, err
+ }
+
+ c.commands = append(c.commands, cmd)
+ return cmd, nil
+}
+
+// AddGroup adds a new group to the command with the given name and data. The
+// data needs to be a pointer to a struct from which the fields indicate which
+// options are in the group.
+func (c *Command) AddGroup(shortDescription string, longDescription string, data interface{}) (*Group, error) {
+ group := newGroup(shortDescription, longDescription, data)
+
+ group.parent = c
+
+ if err := group.scanType(c.scanSubcommandHandler(group)); err != nil {
+ return nil, err
+ }
+
+ c.groups = append(c.groups, group)
+ return group, nil
+}
+
+// Commands returns a list of subcommands of this command.
+func (c *Command) Commands() []*Command {
+ return c.commands
+}
+
+// Find locates the subcommand with the given name and returns it. If no such
+// command can be found Find will return nil.
+func (c *Command) Find(name string) *Command {
+ for _, cc := range c.commands {
+ if cc.match(name) {
+ return cc
+ }
+ }
+
+ return nil
+}
+
+// FindOptionByLongName finds an option that is part of the command, or any of
+// its parent commands, by matching its long name (including the option
+// namespace).
+func (c *Command) FindOptionByLongName(longName string) (option *Option) {
+ for option == nil && c != nil {
+ option = c.Group.FindOptionByLongName(longName)
+
+ c, _ = c.parent.(*Command)
+ }
+
+ return option
+}
+
+// FindOptionByShortName finds an option that is part of the command, or any of
+// its parent commands, by matching its long name (including the option
+// namespace).
+func (c *Command) FindOptionByShortName(shortName rune) (option *Option) {
+ for option == nil && c != nil {
+ option = c.Group.FindOptionByShortName(shortName)
+
+ c, _ = c.parent.(*Command)
+ }
+
+ return option
+}
+
+// Args returns a list of positional arguments associated with this command.
+func (c *Command) Args() []*Arg {
+ ret := make([]*Arg, len(c.args))
+ copy(ret, c.args)
+
+ return ret
+}
+
+func newCommand(name string, shortDescription string, longDescription string, data interface{}) *Command {
+ return &Command{
+ Group: newGroup(shortDescription, longDescription, data),
+ Name: name,
+ }
+}
+
+func (c *Command) scanSubcommandHandler(parentg *Group) scanHandler {
+ f := func(realval reflect.Value, sfield *reflect.StructField) (bool, error) {
+ mtag := newMultiTag(string(sfield.Tag))
+
+ if err := mtag.Parse(); err != nil {
+ return true, err
+ }
+
+ positional := mtag.Get("positional-args")
+
+ if len(positional) != 0 {
+ stype := realval.Type()
+
+ for i := 0; i < stype.NumField(); i++ {
+ field := stype.Field(i)
+
+ m := newMultiTag((string(field.Tag)))
+
+ if err := m.Parse(); err != nil {
+ return true, err
+ }
+
+ name := m.Get("positional-arg-name")
+
+ if len(name) == 0 {
+ name = field.Name
+ }
+
+ required := -1
+ requiredMaximum := -1
+
+ sreq := m.Get("required")
+
+ if sreq != "" {
+ required = 1
+
+ rng := strings.SplitN(sreq, "-", 2)
+
+ if len(rng) > 1 {
+ if preq, err := strconv.ParseInt(rng[0], 10, 32); err == nil {
+ required = int(preq)
+ }
+
+ if preq, err := strconv.ParseInt(rng[1], 10, 32); err == nil {
+ requiredMaximum = int(preq)
+ }
+ } else {
+ if preq, err := strconv.ParseInt(sreq, 10, 32); err == nil {
+ required = int(preq)
+ }
+ }
+ }
+
+ arg := &Arg{
+ Name: name,
+ Description: m.Get("description"),
+ Required: required,
+ RequiredMaximum: requiredMaximum,
+
+ value: realval.Field(i),
+ tag: m,
+ }
+
+ c.args = append(c.args, arg)
+
+ if len(mtag.Get("required")) != 0 {
+ c.ArgsRequired = true
+ }
+ }
+
+ return true, nil
+ }
+
+ subcommand := mtag.Get("command")
+
+ if len(subcommand) != 0 {
+ var ptrval reflect.Value
+
+ if realval.Kind() == reflect.Ptr {
+ ptrval = realval
+
+ if ptrval.IsNil() {
+ ptrval.Set(reflect.New(ptrval.Type().Elem()))
+ }
+ } else {
+ ptrval = realval.Addr()
+ }
+
+ shortDescription := mtag.Get("description")
+ longDescription := mtag.Get("long-description")
+ subcommandsOptional := mtag.Get("subcommands-optional")
+ aliases := mtag.GetMany("alias")
+
+ subc, err := c.AddCommand(subcommand, shortDescription, longDescription, ptrval.Interface())
+
+ if err != nil {
+ return true, err
+ }
+
+ subc.Hidden = mtag.Get("hidden") != ""
+
+ if len(subcommandsOptional) > 0 {
+ subc.SubcommandsOptional = true
+ }
+
+ if len(aliases) > 0 {
+ subc.Aliases = aliases
+ }
+
+ return true, nil
+ }
+
+ return parentg.scanSubGroupHandler(realval, sfield)
+ }
+
+ return f
+}
+
+func (c *Command) scan() error {
+ return c.scanType(c.scanSubcommandHandler(c.Group))
+}
+
+func (c *Command) eachOption(f func(*Command, *Group, *Option)) {
+ c.eachCommand(func(c *Command) {
+ c.eachGroup(func(g *Group) {
+ for _, option := range g.options {
+ f(c, g, option)
+ }
+ })
+ }, true)
+}
+
+func (c *Command) eachCommand(f func(*Command), recurse bool) {
+ f(c)
+
+ for _, cc := range c.commands {
+ if recurse {
+ cc.eachCommand(f, true)
+ } else {
+ f(cc)
+ }
+ }
+}
+
+func (c *Command) eachActiveGroup(f func(cc *Command, g *Group)) {
+ c.eachGroup(func(g *Group) {
+ f(c, g)
+ })
+
+ if c.Active != nil {
+ c.Active.eachActiveGroup(f)
+ }
+}
+
+func (c *Command) addHelpGroups(showHelp func() error) {
+ if !c.hasBuiltinHelpGroup {
+ c.addHelpGroup(showHelp)
+ c.hasBuiltinHelpGroup = true
+ }
+
+ for _, cc := range c.commands {
+ cc.addHelpGroups(showHelp)
+ }
+}
+
+func (c *Command) makeLookup() lookup {
+ ret := lookup{
+ shortNames: make(map[string]*Option),
+ longNames: make(map[string]*Option),
+ commands: make(map[string]*Command),
+ }
+
+ parent := c.parent
+
+ var parents []*Command
+
+ for parent != nil {
+ if cmd, ok := parent.(*Command); ok {
+ parents = append(parents, cmd)
+ parent = cmd.parent
+ } else {
+ parent = nil
+ }
+ }
+
+ for i := len(parents) - 1; i >= 0; i-- {
+ parents[i].fillLookup(&ret, true)
+ }
+
+ c.fillLookup(&ret, false)
+ return ret
+}
+
+func (c *Command) fillLookup(ret *lookup, onlyOptions bool) {
+ c.eachGroup(func(g *Group) {
+ for _, option := range g.options {
+ if option.ShortName != 0 {
+ ret.shortNames[string(option.ShortName)] = option
+ }
+
+ if len(option.LongName) > 0 {
+ ret.longNames[option.LongNameWithNamespace()] = option
+ }
+ }
+ })
+
+ if onlyOptions {
+ return
+ }
+
+ for _, subcommand := range c.commands {
+ ret.commands[subcommand.Name] = subcommand
+
+ for _, a := range subcommand.Aliases {
+ ret.commands[a] = subcommand
+ }
+ }
+}
+
+func (c *Command) groupByName(name string) *Group {
+ if grp := c.Group.groupByName(name); grp != nil {
+ return grp
+ }
+
+ for _, subc := range c.commands {
+ prefix := subc.Name + "."
+
+ if strings.HasPrefix(name, prefix) {
+ if grp := subc.groupByName(name[len(prefix):]); grp != nil {
+ return grp
+ }
+ } else if name == subc.Name {
+ return subc.Group
+ }
+ }
+
+ return nil
+}
+
+type commandList []*Command
+
+func (c commandList) Less(i, j int) bool {
+ return c[i].Name < c[j].Name
+}
+
+func (c commandList) Len() int {
+ return len(c)
+}
+
+func (c commandList) Swap(i, j int) {
+ c[i], c[j] = c[j], c[i]
+}
+
+func (c *Command) sortedVisibleCommands() []*Command {
+ ret := commandList(c.visibleCommands())
+ sort.Sort(ret)
+
+ return []*Command(ret)
+}
+
+func (c *Command) visibleCommands() []*Command {
+ ret := make([]*Command, 0, len(c.commands))
+
+ for _, cmd := range c.commands {
+ if !cmd.Hidden {
+ ret = append(ret, cmd)
+ }
+ }
+
+ return ret
+}
+
+func (c *Command) match(name string) bool {
+ if c.Name == name {
+ return true
+ }
+
+ for _, v := range c.Aliases {
+ if v == name {
+ return true
+ }
+ }
+
+ return false
+}
+
+func (c *Command) hasCliOptions() bool {
+ ret := false
+
+ c.eachGroup(func(g *Group) {
+ if g.isBuiltinHelp {
+ return
+ }
+
+ for _, opt := range g.options {
+ if opt.canCli() {
+ ret = true
+ }
+ }
+ })
+
+ return ret
+}
+
+func (c *Command) fillParseState(s *parseState) {
+ s.positional = make([]*Arg, len(c.args))
+ copy(s.positional, c.args)
+
+ s.lookup = c.makeLookup()
+ s.command = c
+}
diff --git a/vendor/github.com/jessevdk/go-flags/completion.go b/vendor/github.com/jessevdk/go-flags/completion.go
new file mode 100644
index 0000000..7a7a08b
--- /dev/null
+++ b/vendor/github.com/jessevdk/go-flags/completion.go
@@ -0,0 +1,309 @@
+package flags
+
+import (
+ "fmt"
+ "path/filepath"
+ "reflect"
+ "sort"
+ "strings"
+ "unicode/utf8"
+)
+
+// Completion is a type containing information of a completion.
+type Completion struct {
+ // The completed item
+ Item string
+
+ // A description of the completed item (optional)
+ Description string
+}
+
+type completions []Completion
+
+func (c completions) Len() int {
+ return len(c)
+}
+
+func (c completions) Less(i, j int) bool {
+ return c[i].Item < c[j].Item
+}
+
+func (c completions) Swap(i, j int) {
+ c[i], c[j] = c[j], c[i]
+}
+
+// Completer is an interface which can be implemented by types
+// to provide custom command line argument completion.
+type Completer interface {
+ // Complete receives a prefix representing a (partial) value
+ // for its type and should provide a list of possible valid
+ // completions.
+ Complete(match string) []Completion
+}
+
+type completion struct {
+ parser *Parser
+}
+
+// Filename is a string alias which provides filename completion.
+type Filename string
+
+func completionsWithoutDescriptions(items []string) []Completion {
+ ret := make([]Completion, len(items))
+
+ for i, v := range items {
+ ret[i].Item = v
+ }
+
+ return ret
+}
+
+// Complete returns a list of existing files with the given
+// prefix.
+func (f *Filename) Complete(match string) []Completion {
+ ret, _ := filepath.Glob(match + "*")
+ return completionsWithoutDescriptions(ret)
+}
+
+func (c *completion) skipPositional(s *parseState, n int) {
+ if n >= len(s.positional) {
+ s.positional = nil
+ } else {
+ s.positional = s.positional[n:]
+ }
+}
+
+func (c *completion) completeOptionNames(s *parseState, prefix string, match string, short bool) []Completion {
+ if short && len(match) != 0 {
+ return []Completion{
+ Completion{
+ Item: prefix + match,
+ },
+ }
+ }
+
+ var results []Completion
+ repeats := map[string]bool{}
+
+ for name, opt := range s.lookup.longNames {
+ if strings.HasPrefix(name, match) && !opt.Hidden {
+ results = append(results, Completion{
+ Item: defaultLongOptDelimiter + name,
+ Description: opt.Description,
+ })
+
+ if short {
+ repeats[string(opt.ShortName)] = true
+ }
+ }
+ }
+
+ if short {
+ for name, opt := range s.lookup.shortNames {
+ if _, exist := repeats[name]; !exist && strings.HasPrefix(name, match) && !opt.Hidden {
+ results = append(results, Completion{
+ Item: string(defaultShortOptDelimiter) + name,
+ Description: opt.Description,
+ })
+ }
+ }
+ }
+
+ return results
+}
+
+func (c *completion) completeNamesForLongPrefix(s *parseState, prefix string, match string) []Completion {
+ return c.completeOptionNames(s, prefix, match, false)
+}
+
+func (c *completion) completeNamesForShortPrefix(s *parseState, prefix string, match string) []Completion {
+ return c.completeOptionNames(s, prefix, match, true)
+}
+
+func (c *completion) completeCommands(s *parseState, match string) []Completion {
+ n := make([]Completion, 0, len(s.command.commands))
+
+ for _, cmd := range s.command.commands {
+ if cmd.data != c && strings.HasPrefix(cmd.Name, match) {
+ n = append(n, Completion{
+ Item: cmd.Name,
+ Description: cmd.ShortDescription,
+ })
+ }
+ }
+
+ return n
+}
+
+func (c *completion) completeValue(value reflect.Value, prefix string, match string) []Completion {
+ if value.Kind() == reflect.Slice {
+ value = reflect.New(value.Type().Elem())
+ }
+ i := value.Interface()
+
+ var ret []Completion
+
+ if cmp, ok := i.(Completer); ok {
+ ret = cmp.Complete(match)
+ } else if value.CanAddr() {
+ if cmp, ok = value.Addr().Interface().(Completer); ok {
+ ret = cmp.Complete(match)
+ }
+ }
+
+ for i, v := range ret {
+ ret[i].Item = prefix + v.Item
+ }
+
+ return ret
+}
+
+func (c *completion) complete(args []string) []Completion {
+ if len(args) == 0 {
+ args = []string{""}
+ }
+
+ s := &parseState{
+ args: args,
+ }
+
+ c.parser.fillParseState(s)
+
+ var opt *Option
+
+ for len(s.args) > 1 {
+ arg := s.pop()
+
+ if (c.parser.Options&PassDoubleDash) != None && arg == "--" {
+ opt = nil
+ c.skipPositional(s, len(s.args)-1)
+
+ break
+ }
+
+ if argumentIsOption(arg) {
+ prefix, optname, islong := stripOptionPrefix(arg)
+ optname, _, argument := splitOption(prefix, optname, islong)
+
+ if argument == nil {
+ var o *Option
+ canarg := true
+
+ if islong {
+ o = s.lookup.longNames[optname]
+ } else {
+ for i, r := range optname {
+ sname := string(r)
+ o = s.lookup.shortNames[sname]
+
+ if o == nil {
+ break
+ }
+
+ if i == 0 && o.canArgument() && len(optname) != len(sname) {
+ canarg = false
+ break
+ }
+ }
+ }
+
+ if o == nil && (c.parser.Options&PassAfterNonOption) != None {
+ opt = nil
+ c.skipPositional(s, len(s.args)-1)
+
+ break
+ } else if o != nil && o.canArgument() && !o.OptionalArgument && canarg {
+ if len(s.args) > 1 {
+ s.pop()
+ } else {
+ opt = o
+ }
+ }
+ }
+ } else {
+ if len(s.positional) > 0 {
+ if !s.positional[0].isRemaining() {
+ // Don't advance beyond a remaining positional arg (because
+ // it consumes all subsequent args).
+ s.positional = s.positional[1:]
+ }
+ } else if cmd, ok := s.lookup.commands[arg]; ok {
+ cmd.fillParseState(s)
+ }
+
+ opt = nil
+ }
+ }
+
+ lastarg := s.args[len(s.args)-1]
+ var ret []Completion
+
+ if opt != nil {
+ // Completion for the argument of 'opt'
+ ret = c.completeValue(opt.value, "", lastarg)
+ } else if argumentStartsOption(lastarg) {
+ // Complete the option
+ prefix, optname, islong := stripOptionPrefix(lastarg)
+ optname, split, argument := splitOption(prefix, optname, islong)
+
+ if argument == nil && !islong {
+ rname, n := utf8.DecodeRuneInString(optname)
+ sname := string(rname)
+
+ if opt := s.lookup.shortNames[sname]; opt != nil && opt.canArgument() {
+ ret = c.completeValue(opt.value, prefix+sname, optname[n:])
+ } else {
+ ret = c.completeNamesForShortPrefix(s, prefix, optname)
+ }
+ } else if argument != nil {
+ if islong {
+ opt = s.lookup.longNames[optname]
+ } else {
+ opt = s.lookup.shortNames[optname]
+ }
+
+ if opt != nil {
+ ret = c.completeValue(opt.value, prefix+optname+split, *argument)
+ }
+ } else if islong {
+ ret = c.completeNamesForLongPrefix(s, prefix, optname)
+ } else {
+ ret = c.completeNamesForShortPrefix(s, prefix, optname)
+ }
+ } else if len(s.positional) > 0 {
+ // Complete for positional argument
+ ret = c.completeValue(s.positional[0].value, "", lastarg)
+ } else if len(s.command.commands) > 0 {
+ // Complete for command
+ ret = c.completeCommands(s, lastarg)
+ }
+
+ sort.Sort(completions(ret))
+ return ret
+}
+
+func (c *completion) print(items []Completion, showDescriptions bool) {
+ if showDescriptions && len(items) > 1 {
+ maxl := 0
+
+ for _, v := range items {
+ if len(v.Item) > maxl {
+ maxl = len(v.Item)
+ }
+ }
+
+ for _, v := range items {
+ fmt.Printf("%s", v.Item)
+
+ if len(v.Description) > 0 {
+ fmt.Printf("%s # %s", strings.Repeat(" ", maxl-len(v.Item)), v.Description)
+ }
+
+ fmt.Printf("\n")
+ }
+ } else {
+ for _, v := range items {
+ fmt.Println(v.Item)
+ }
+ }
+}
diff --git a/vendor/github.com/jessevdk/go-flags/convert.go b/vendor/github.com/jessevdk/go-flags/convert.go
new file mode 100644
index 0000000..984aac8
--- /dev/null
+++ b/vendor/github.com/jessevdk/go-flags/convert.go
@@ -0,0 +1,348 @@
+// Copyright 2012 Jesse van den Kieboom. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package flags
+
+import (
+ "fmt"
+ "reflect"
+ "strconv"
+ "strings"
+ "time"
+)
+
+// Marshaler is the interface implemented by types that can marshal themselves
+// to a string representation of the flag.
+type Marshaler interface {
+ // MarshalFlag marshals a flag value to its string representation.
+ MarshalFlag() (string, error)
+}
+
+// Unmarshaler is the interface implemented by types that can unmarshal a flag
+// argument to themselves. The provided value is directly passed from the
+// command line.
+type Unmarshaler interface {
+ // UnmarshalFlag unmarshals a string value representation to the flag
+ // value (which therefore needs to be a pointer receiver).
+ UnmarshalFlag(value string) error
+}
+
+func getBase(options multiTag, base int) (int, error) {
+ sbase := options.Get("base")
+
+ var err error
+ var ivbase int64
+
+ if sbase != "" {
+ ivbase, err = strconv.ParseInt(sbase, 10, 32)
+ base = int(ivbase)
+ }
+
+ return base, err
+}
+
+func convertMarshal(val reflect.Value) (bool, string, error) {
+ // Check first for the Marshaler interface
+ if val.Type().NumMethod() > 0 && val.CanInterface() {
+ if marshaler, ok := val.Interface().(Marshaler); ok {
+ ret, err := marshaler.MarshalFlag()
+ return true, ret, err
+ }
+ }
+
+ return false, "", nil
+}
+
+func convertToString(val reflect.Value, options multiTag) (string, error) {
+ if ok, ret, err := convertMarshal(val); ok {
+ return ret, err
+ }
+
+ tp := val.Type()
+
+ // Support for time.Duration
+ if tp == reflect.TypeOf((*time.Duration)(nil)).Elem() {
+ stringer := val.Interface().(fmt.Stringer)
+ return stringer.String(), nil
+ }
+
+ switch tp.Kind() {
+ case reflect.String:
+ return val.String(), nil
+ case reflect.Bool:
+ if val.Bool() {
+ return "true", nil
+ }
+
+ return "false", nil
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ base, err := getBase(options, 10)
+
+ if err != nil {
+ return "", err
+ }
+
+ return strconv.FormatInt(val.Int(), base), nil
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ base, err := getBase(options, 10)
+
+ if err != nil {
+ return "", err
+ }
+
+ return strconv.FormatUint(val.Uint(), base), nil
+ case reflect.Float32, reflect.Float64:
+ return strconv.FormatFloat(val.Float(), 'g', -1, tp.Bits()), nil
+ case reflect.Slice:
+ if val.Len() == 0 {
+ return "", nil
+ }
+
+ ret := "["
+
+ for i := 0; i < val.Len(); i++ {
+ if i != 0 {
+ ret += ", "
+ }
+
+ item, err := convertToString(val.Index(i), options)
+
+ if err != nil {
+ return "", err
+ }
+
+ ret += item
+ }
+
+ return ret + "]", nil
+ case reflect.Map:
+ ret := "{"
+
+ for i, key := range val.MapKeys() {
+ if i != 0 {
+ ret += ", "
+ }
+
+ keyitem, err := convertToString(key, options)
+
+ if err != nil {
+ return "", err
+ }
+
+ item, err := convertToString(val.MapIndex(key), options)
+
+ if err != nil {
+ return "", err
+ }
+
+ ret += keyitem + ":" + item
+ }
+
+ return ret + "}", nil
+ case reflect.Ptr:
+ return convertToString(reflect.Indirect(val), options)
+ case reflect.Interface:
+ if !val.IsNil() {
+ return convertToString(val.Elem(), options)
+ }
+ }
+
+ return "", nil
+}
+
+func convertUnmarshal(val string, retval reflect.Value) (bool, error) {
+ if retval.Type().NumMethod() > 0 && retval.CanInterface() {
+ if unmarshaler, ok := retval.Interface().(Unmarshaler); ok {
+ if retval.IsNil() {
+ retval.Set(reflect.New(retval.Type().Elem()))
+
+ // Re-assign from the new value
+ unmarshaler = retval.Interface().(Unmarshaler)
+ }
+
+ return true, unmarshaler.UnmarshalFlag(val)
+ }
+ }
+
+ if retval.Type().Kind() != reflect.Ptr && retval.CanAddr() {
+ return convertUnmarshal(val, retval.Addr())
+ }
+
+ if retval.Type().Kind() == reflect.Interface && !retval.IsNil() {
+ return convertUnmarshal(val, retval.Elem())
+ }
+
+ return false, nil
+}
+
+func convert(val string, retval reflect.Value, options multiTag) error {
+ if ok, err := convertUnmarshal(val, retval); ok {
+ return err
+ }
+
+ tp := retval.Type()
+
+ // Support for time.Duration
+ if tp == reflect.TypeOf((*time.Duration)(nil)).Elem() {
+ parsed, err := time.ParseDuration(val)
+
+ if err != nil {
+ return err
+ }
+
+ retval.SetInt(int64(parsed))
+ return nil
+ }
+
+ switch tp.Kind() {
+ case reflect.String:
+ retval.SetString(val)
+ case reflect.Bool:
+ if val == "" {
+ retval.SetBool(true)
+ } else {
+ b, err := strconv.ParseBool(val)
+
+ if err != nil {
+ return err
+ }
+
+ retval.SetBool(b)
+ }
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ base, err := getBase(options, 10)
+
+ if err != nil {
+ return err
+ }
+
+ parsed, err := strconv.ParseInt(val, base, tp.Bits())
+
+ if err != nil {
+ return err
+ }
+
+ retval.SetInt(parsed)
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ base, err := getBase(options, 10)
+
+ if err != nil {
+ return err
+ }
+
+ parsed, err := strconv.ParseUint(val, base, tp.Bits())
+
+ if err != nil {
+ return err
+ }
+
+ retval.SetUint(parsed)
+ case reflect.Float32, reflect.Float64:
+ parsed, err := strconv.ParseFloat(val, tp.Bits())
+
+ if err != nil {
+ return err
+ }
+
+ retval.SetFloat(parsed)
+ case reflect.Slice:
+ elemtp := tp.Elem()
+
+ elemvalptr := reflect.New(elemtp)
+ elemval := reflect.Indirect(elemvalptr)
+
+ if err := convert(val, elemval, options); err != nil {
+ return err
+ }
+
+ retval.Set(reflect.Append(retval, elemval))
+ case reflect.Map:
+ parts := strings.SplitN(val, ":", 2)
+
+ key := parts[0]
+ var value string
+
+ if len(parts) == 2 {
+ value = parts[1]
+ }
+
+ keytp := tp.Key()
+ keyval := reflect.New(keytp)
+
+ if err := convert(key, keyval, options); err != nil {
+ return err
+ }
+
+ valuetp := tp.Elem()
+ valueval := reflect.New(valuetp)
+
+ if err := convert(value, valueval, options); err != nil {
+ return err
+ }
+
+ if retval.IsNil() {
+ retval.Set(reflect.MakeMap(tp))
+ }
+
+ retval.SetMapIndex(reflect.Indirect(keyval), reflect.Indirect(valueval))
+ case reflect.Ptr:
+ if retval.IsNil() {
+ retval.Set(reflect.New(retval.Type().Elem()))
+ }
+
+ return convert(val, reflect.Indirect(retval), options)
+ case reflect.Interface:
+ if !retval.IsNil() {
+ return convert(val, retval.Elem(), options)
+ }
+ }
+
+ return nil
+}
+
+func isPrint(s string) bool {
+ for _, c := range s {
+ if !strconv.IsPrint(c) {
+ return false
+ }
+ }
+
+ return true
+}
+
+func quoteIfNeeded(s string) string {
+ if !isPrint(s) {
+ return strconv.Quote(s)
+ }
+
+ return s
+}
+
+func quoteIfNeededV(s []string) []string {
+ ret := make([]string, len(s))
+
+ for i, v := range s {
+ ret[i] = quoteIfNeeded(v)
+ }
+
+ return ret
+}
+
+func quoteV(s []string) []string {
+ ret := make([]string, len(s))
+
+ for i, v := range s {
+ ret[i] = strconv.Quote(v)
+ }
+
+ return ret
+}
+
+func unquoteIfPossible(s string) (string, error) {
+ if len(s) == 0 || s[0] != '"' {
+ return s, nil
+ }
+
+ return strconv.Unquote(s)
+}
diff --git a/vendor/github.com/jessevdk/go-flags/error.go b/vendor/github.com/jessevdk/go-flags/error.go
new file mode 100644
index 0000000..05528d8
--- /dev/null
+++ b/vendor/github.com/jessevdk/go-flags/error.go
@@ -0,0 +1,134 @@
+package flags
+
+import (
+ "fmt"
+)
+
+// ErrorType represents the type of error.
+type ErrorType uint
+
+const (
+ // ErrUnknown indicates a generic error.
+ ErrUnknown ErrorType = iota
+
+ // ErrExpectedArgument indicates that an argument was expected.
+ ErrExpectedArgument
+
+ // ErrUnknownFlag indicates an unknown flag.
+ ErrUnknownFlag
+
+ // ErrUnknownGroup indicates an unknown group.
+ ErrUnknownGroup
+
+ // ErrMarshal indicates a marshalling error while converting values.
+ ErrMarshal
+
+ // ErrHelp indicates that the built-in help was shown (the error
+ // contains the help message).
+ ErrHelp
+
+ // ErrNoArgumentForBool indicates that an argument was given for a
+ // boolean flag (which don't not take any arguments).
+ ErrNoArgumentForBool
+
+ // ErrRequired indicates that a required flag was not provided.
+ ErrRequired
+
+ // ErrShortNameTooLong indicates that a short flag name was specified,
+ // longer than one character.
+ ErrShortNameTooLong
+
+ // ErrDuplicatedFlag indicates that a short or long flag has been
+ // defined more than once
+ ErrDuplicatedFlag
+
+ // ErrTag indicates an error while parsing flag tags.
+ ErrTag
+
+ // ErrCommandRequired indicates that a command was required but not
+ // specified
+ ErrCommandRequired
+
+ // ErrUnknownCommand indicates that an unknown command was specified.
+ ErrUnknownCommand
+
+ // ErrInvalidChoice indicates an invalid option value which only allows
+ // a certain number of choices.
+ ErrInvalidChoice
+
+ // ErrInvalidTag indicates an invalid tag or invalid use of an existing tag
+ ErrInvalidTag
+)
+
+func (e ErrorType) String() string {
+ switch e {
+ case ErrUnknown:
+ return "unknown"
+ case ErrExpectedArgument:
+ return "expected argument"
+ case ErrUnknownFlag:
+ return "unknown flag"
+ case ErrUnknownGroup:
+ return "unknown group"
+ case ErrMarshal:
+ return "marshal"
+ case ErrHelp:
+ return "help"
+ case ErrNoArgumentForBool:
+ return "no argument for bool"
+ case ErrRequired:
+ return "required"
+ case ErrShortNameTooLong:
+ return "short name too long"
+ case ErrDuplicatedFlag:
+ return "duplicated flag"
+ case ErrTag:
+ return "tag"
+ case ErrCommandRequired:
+ return "command required"
+ case ErrUnknownCommand:
+ return "unknown command"
+ case ErrInvalidChoice:
+ return "invalid choice"
+ case ErrInvalidTag:
+ return "invalid tag"
+ }
+
+ return "unrecognized error type"
+}
+
+// Error represents a parser error. The error returned from Parse is of this
+// type. The error contains both a Type and Message.
+type Error struct {
+ // The type of error
+ Type ErrorType
+
+ // The error message
+ Message string
+}
+
+// Error returns the error's message
+func (e *Error) Error() string {
+ return e.Message
+}
+
+func newError(tp ErrorType, message string) *Error {
+ return &Error{
+ Type: tp,
+ Message: message,
+ }
+}
+
+func newErrorf(tp ErrorType, format string, args ...interface{}) *Error {
+ return newError(tp, fmt.Sprintf(format, args...))
+}
+
+func wrapError(err error) *Error {
+ ret, ok := err.(*Error)
+
+ if !ok {
+ return newError(ErrUnknown, err.Error())
+ }
+
+ return ret
+}
diff --git a/vendor/github.com/jessevdk/go-flags/flags.go b/vendor/github.com/jessevdk/go-flags/flags.go
new file mode 100644
index 0000000..889762d
--- /dev/null
+++ b/vendor/github.com/jessevdk/go-flags/flags.go
@@ -0,0 +1,258 @@
+// Copyright 2012 Jesse van den Kieboom. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+Package flags provides an extensive command line option parser.
+The flags package is similar in functionality to the go built-in flag package
+but provides more options and uses reflection to provide a convenient and
+succinct way of specifying command line options.
+
+
+Supported features
+
+The following features are supported in go-flags:
+
+ Options with short names (-v)
+ Options with long names (--verbose)
+ Options with and without arguments (bool v.s. other type)
+ Options with optional arguments and default values
+ Option default values from ENVIRONMENT_VARIABLES, including slice and map values
+ Multiple option groups each containing a set of options
+ Generate and print well-formatted help message
+ Passing remaining command line arguments after -- (optional)
+ Ignoring unknown command line options (optional)
+ Supports -I/usr/include -I=/usr/include -I /usr/include option argument specification
+ Supports multiple short options -aux
+ Supports all primitive go types (string, int{8..64}, uint{8..64}, float)
+ Supports same option multiple times (can store in slice or last option counts)
+ Supports maps
+ Supports function callbacks
+ Supports namespaces for (nested) option groups
+
+Additional features specific to Windows:
+ Options with short names (/v)
+ Options with long names (/verbose)
+ Windows-style options with arguments use a colon as the delimiter
+ Modify generated help message with Windows-style / options
+ Windows style options can be disabled at build time using the "forceposix"
+ build tag
+
+
+Basic usage
+
+The flags package uses structs, reflection and struct field tags
+to allow users to specify command line options. This results in very simple
+and concise specification of your application options. For example:
+
+ type Options struct {
+ Verbose []bool `short:"v" long:"verbose" description:"Show verbose debug information"`
+ }
+
+This specifies one option with a short name -v and a long name --verbose.
+When either -v or --verbose is found on the command line, a 'true' value
+will be appended to the Verbose field. e.g. when specifying -vvv, the
+resulting value of Verbose will be {[true, true, true]}.
+
+Slice options work exactly the same as primitive type options, except that
+whenever the option is encountered, a value is appended to the slice.
+
+Map options from string to primitive type are also supported. On the command
+line, you specify the value for such an option as key:value. For example
+
+ type Options struct {
+ AuthorInfo string[string] `short:"a"`
+ }
+
+Then, the AuthorInfo map can be filled with something like
+-a name:Jesse -a "surname:van den Kieboom".
+
+Finally, for full control over the conversion between command line argument
+values and options, user defined types can choose to implement the Marshaler
+and Unmarshaler interfaces.
+
+
+Available field tags
+
+The following is a list of tags for struct fields supported by go-flags:
+
+ short: the short name of the option (single character)
+ long: the long name of the option
+ required: if non empty, makes the option required to appear on the command
+ line. If a required option is not present, the parser will
+ return ErrRequired (optional)
+ description: the description of the option (optional)
+ long-description: the long description of the option. Currently only
+ displayed in generated man pages (optional)
+ no-flag: if non-empty, this field is ignored as an option (optional)
+
+ optional: if non-empty, makes the argument of the option optional. When an
+ argument is optional it can only be specified using
+ --option=argument (optional)
+ optional-value: the value of an optional option when the option occurs
+ without an argument. This tag can be specified multiple
+ times in the case of maps or slices (optional)
+ default: the default value of an option. This tag can be specified
+ multiple times in the case of slices or maps (optional)
+ default-mask: when specified, this value will be displayed in the help
+ instead of the actual default value. This is useful
+ mostly for hiding otherwise sensitive information from
+ showing up in the help. If default-mask takes the special
+ value "-", then no default value will be shown at all
+ (optional)
+ env: the default value of the option is overridden from the
+ specified environment variable, if one has been defined.
+ (optional)
+ env-delim: the 'env' default value from environment is split into
+ multiple values with the given delimiter string, use with
+ slices and maps (optional)
+ value-name: the name of the argument value (to be shown in the help)
+ (optional)
+ choice: limits the values for an option to a set of values.
+ This tag can be specified multiple times (optional)
+ hidden: if non-empty, the option is not visible in the help or man page.
+
+ base: a base (radix) used to convert strings to integer values, the
+ default base is 10 (i.e. decimal) (optional)
+
+ ini-name: the explicit ini option name (optional)
+ no-ini: if non-empty this field is ignored as an ini option
+ (optional)
+
+ group: when specified on a struct field, makes the struct
+ field a separate group with the given name (optional)
+ namespace: when specified on a group struct field, the namespace
+ gets prepended to every option's long name and
+ subgroup's namespace of this group, separated by
+ the parser's namespace delimiter (optional)
+ command: when specified on a struct field, makes the struct
+ field a (sub)command with the given name (optional)
+ subcommands-optional: when specified on a command struct field, makes
+ any subcommands of that command optional (optional)
+ alias: when specified on a command struct field, adds the
+ specified name as an alias for the command. Can be
+ be specified multiple times to add more than one
+ alias (optional)
+ positional-args: when specified on a field with a struct type,
+ uses the fields of that struct to parse remaining
+ positional command line arguments into (in order
+ of the fields). If a field has a slice type,
+ then all remaining arguments will be added to it.
+ Positional arguments are optional by default,
+ unless the "required" tag is specified together
+ with the "positional-args" tag. The "required" tag
+ can also be set on the individual rest argument
+ fields, to require only the first N positional
+ arguments. If the "required" tag is set on the
+ rest arguments slice, then its value determines
+ the minimum amount of rest arguments that needs to
+ be provided (e.g. `required:"2"`) (optional)
+ positional-arg-name: used on a field in a positional argument struct; name
+ of the positional argument placeholder to be shown in
+ the help (optional)
+
+Either the `short:` tag or the `long:` must be specified to make the field eligible as an
+option.
+
+
+Option groups
+
+Option groups are a simple way to semantically separate your options. All
+options in a particular group are shown together in the help under the name
+of the group. Namespaces can be used to specify option long names more
+precisely and emphasize the options affiliation to their group.
+
+There are currently three ways to specify option groups.
+
+ 1. Use NewNamedParser specifying the various option groups.
+ 2. Use AddGroup to add a group to an existing parser.
+ 3. Add a struct field to the top-level options annotated with the
+ group:"group-name" tag.
+
+
+
+Commands
+
+The flags package also has basic support for commands. Commands are often
+used in monolithic applications that support various commands or actions.
+Take git for example, all of the add, commit, checkout, etc. are called
+commands. Using commands you can easily separate multiple functions of your
+application.
+
+There are currently two ways to specify a command.
+
+ 1. Use AddCommand on an existing parser.
+ 2. Add a struct field to your options struct annotated with the
+ command:"command-name" tag.
+
+The most common, idiomatic way to implement commands is to define a global
+parser instance and implement each command in a separate file. These
+command files should define a go init function which calls AddCommand on
+the global parser.
+
+When parsing ends and there is an active command and that command implements
+the Commander interface, then its Execute method will be run with the
+remaining command line arguments.
+
+Command structs can have options which become valid to parse after the
+command has been specified on the command line, in addition to the options
+of all the parent commands. I.e. considering a -v flag on the parser and an
+add command, the following are equivalent:
+
+ ./app -v add
+ ./app add -v
+
+However, if the -v flag is defined on the add command, then the first of
+the two examples above would fail since the -v flag is not defined before
+the add command.
+
+
+Completion
+
+go-flags has builtin support to provide bash completion of flags, commands
+and argument values. To use completion, the binary which uses go-flags
+can be invoked in a special environment to list completion of the current
+command line argument. It should be noted that this `executes` your application,
+and it is up to the user to make sure there are no negative side effects (for
+example from init functions).
+
+Setting the environment variable `GO_FLAGS_COMPLETION=1` enables completion
+by replacing the argument parsing routine with the completion routine which
+outputs completions for the passed arguments. The basic invocation to
+complete a set of arguments is therefore:
+
+ GO_FLAGS_COMPLETION=1 ./completion-example arg1 arg2 arg3
+
+where `completion-example` is the binary, `arg1` and `arg2` are
+the current arguments, and `arg3` (the last argument) is the argument
+to be completed. If the GO_FLAGS_COMPLETION is set to "verbose", then
+descriptions of possible completion items will also be shown, if there
+are more than 1 completion items.
+
+To use this with bash completion, a simple file can be written which
+calls the binary which supports go-flags completion:
+
+ _completion_example() {
+ # All arguments except the first one
+ args=("${COMP_WORDS[@]:1:$COMP_CWORD}")
+
+ # Only split on newlines
+ local IFS=$'\n'
+
+ # Call completion (note that the first element of COMP_WORDS is
+ # the executable itself)
+ COMPREPLY=($(GO_FLAGS_COMPLETION=1 ${COMP_WORDS[0]} "${args[@]}"))
+ return 0
+ }
+
+ complete -F _completion_example completion-example
+
+Completion requires the parser option PassDoubleDash and is therefore enforced if the environment variable GO_FLAGS_COMPLETION is set.
+
+Customized completion for argument values is supported by implementing
+the flags.Completer interface for the argument value type. An example
+of a type which does so is the flags.Filename type, an alias of string
+allowing simple filename completion. A slice or array argument value
+whose element type implements flags.Completer will also be completed.
+*/
+package flags
diff --git a/vendor/github.com/jessevdk/go-flags/group.go b/vendor/github.com/jessevdk/go-flags/group.go
new file mode 100644
index 0000000..9e057ab
--- /dev/null
+++ b/vendor/github.com/jessevdk/go-flags/group.go
@@ -0,0 +1,406 @@
+// Copyright 2012 Jesse van den Kieboom. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package flags
+
+import (
+ "errors"
+ "reflect"
+ "strings"
+ "unicode/utf8"
+)
+
+// ErrNotPointerToStruct indicates that a provided data container is not
+// a pointer to a struct. Only pointers to structs are valid data containers
+// for options.
+var ErrNotPointerToStruct = errors.New("provided data is not a pointer to struct")
+
+// Group represents an option group. Option groups can be used to logically
+// group options together under a description. Groups are only used to provide
+// more structure to options both for the user (as displayed in the help message)
+// and for you, since groups can be nested.
+type Group struct {
+ // A short description of the group. The
+ // short description is primarily used in the built-in generated help
+ // message
+ ShortDescription string
+
+ // A long description of the group. The long
+ // description is primarily used to present information on commands
+ // (Command embeds Group) in the built-in generated help and man pages.
+ LongDescription string
+
+ // The namespace of the group
+ Namespace string
+
+ // If true, the group is not displayed in the help or man page
+ Hidden bool
+
+ // The parent of the group or nil if it has no parent
+ parent interface{}
+
+ // All the options in the group
+ options []*Option
+
+ // All the subgroups
+ groups []*Group
+
+ // Whether the group represents the built-in help group
+ isBuiltinHelp bool
+
+ data interface{}
+}
+
+type scanHandler func(reflect.Value, *reflect.StructField) (bool, error)
+
+// AddGroup adds a new group to the command with the given name and data. The
+// data needs to be a pointer to a struct from which the fields indicate which
+// options are in the group.
+func (g *Group) AddGroup(shortDescription string, longDescription string, data interface{}) (*Group, error) {
+ group := newGroup(shortDescription, longDescription, data)
+
+ group.parent = g
+
+ if err := group.scan(); err != nil {
+ return nil, err
+ }
+
+ g.groups = append(g.groups, group)
+ return group, nil
+}
+
+// Groups returns the list of groups embedded in this group.
+func (g *Group) Groups() []*Group {
+ return g.groups
+}
+
+// Options returns the list of options in this group.
+func (g *Group) Options() []*Option {
+ return g.options
+}
+
+// Find locates the subgroup with the given short description and returns it.
+// If no such group can be found Find will return nil. Note that the description
+// is matched case insensitively.
+func (g *Group) Find(shortDescription string) *Group {
+ lshortDescription := strings.ToLower(shortDescription)
+
+ var ret *Group
+
+ g.eachGroup(func(gg *Group) {
+ if gg != g && strings.ToLower(gg.ShortDescription) == lshortDescription {
+ ret = gg
+ }
+ })
+
+ return ret
+}
+
+func (g *Group) findOption(matcher func(*Option) bool) (option *Option) {
+ g.eachGroup(func(g *Group) {
+ for _, opt := range g.options {
+ if option == nil && matcher(opt) {
+ option = opt
+ }
+ }
+ })
+
+ return option
+}
+
+// FindOptionByLongName finds an option that is part of the group, or any of its
+// subgroups, by matching its long name (including the option namespace).
+func (g *Group) FindOptionByLongName(longName string) *Option {
+ return g.findOption(func(option *Option) bool {
+ return option.LongNameWithNamespace() == longName
+ })
+}
+
+// FindOptionByShortName finds an option that is part of the group, or any of
+// its subgroups, by matching its short name.
+func (g *Group) FindOptionByShortName(shortName rune) *Option {
+ return g.findOption(func(option *Option) bool {
+ return option.ShortName == shortName
+ })
+}
+
+func newGroup(shortDescription string, longDescription string, data interface{}) *Group {
+ return &Group{
+ ShortDescription: shortDescription,
+ LongDescription: longDescription,
+
+ data: data,
+ }
+}
+
+func (g *Group) optionByName(name string, namematch func(*Option, string) bool) *Option {
+ prio := 0
+ var retopt *Option
+
+ g.eachGroup(func(g *Group) {
+ for _, opt := range g.options {
+ if namematch != nil && namematch(opt, name) && prio < 4 {
+ retopt = opt
+ prio = 4
+ }
+
+ if name == opt.field.Name && prio < 3 {
+ retopt = opt
+ prio = 3
+ }
+
+ if name == opt.LongNameWithNamespace() && prio < 2 {
+ retopt = opt
+ prio = 2
+ }
+
+ if opt.ShortName != 0 && name == string(opt.ShortName) && prio < 1 {
+ retopt = opt
+ prio = 1
+ }
+ }
+ })
+
+ return retopt
+}
+
+func (g *Group) eachGroup(f func(*Group)) {
+ f(g)
+
+ for _, gg := range g.groups {
+ gg.eachGroup(f)
+ }
+}
+
+func isStringFalsy(s string) bool {
+ return s == "" || s == "false" || s == "no" || s == "0"
+}
+
+func (g *Group) scanStruct(realval reflect.Value, sfield *reflect.StructField, handler scanHandler) error {
+ stype := realval.Type()
+
+ if sfield != nil {
+ if ok, err := handler(realval, sfield); err != nil {
+ return err
+ } else if ok {
+ return nil
+ }
+ }
+
+ for i := 0; i < stype.NumField(); i++ {
+ field := stype.Field(i)
+
+ // PkgName is set only for non-exported fields, which we ignore
+ if field.PkgPath != "" && !field.Anonymous {
+ continue
+ }
+
+ mtag := newMultiTag(string(field.Tag))
+
+ if err := mtag.Parse(); err != nil {
+ return err
+ }
+
+ // Skip fields with the no-flag tag
+ if mtag.Get("no-flag") != "" {
+ continue
+ }
+
+ // Dive deep into structs or pointers to structs
+ kind := field.Type.Kind()
+ fld := realval.Field(i)
+
+ if kind == reflect.Struct {
+ if err := g.scanStruct(fld, &field, handler); err != nil {
+ return err
+ }
+ } else if kind == reflect.Ptr && field.Type.Elem().Kind() == reflect.Struct {
+ flagCountBefore := len(g.options) + len(g.groups)
+
+ if fld.IsNil() {
+ fld = reflect.New(fld.Type().Elem())
+ }
+
+ if err := g.scanStruct(reflect.Indirect(fld), &field, handler); err != nil {
+ return err
+ }
+
+ if len(g.options)+len(g.groups) != flagCountBefore {
+ realval.Field(i).Set(fld)
+ }
+ }
+
+ longname := mtag.Get("long")
+ shortname := mtag.Get("short")
+
+ // Need at least either a short or long name
+ if longname == "" && shortname == "" && mtag.Get("ini-name") == "" {
+ continue
+ }
+
+ short := rune(0)
+ rc := utf8.RuneCountInString(shortname)
+
+ if rc > 1 {
+ return newErrorf(ErrShortNameTooLong,
+ "short names can only be 1 character long, not `%s'",
+ shortname)
+
+ } else if rc == 1 {
+ short, _ = utf8.DecodeRuneInString(shortname)
+ }
+
+ description := mtag.Get("description")
+ def := mtag.GetMany("default")
+
+ optionalValue := mtag.GetMany("optional-value")
+ valueName := mtag.Get("value-name")
+ defaultMask := mtag.Get("default-mask")
+
+ optional := !isStringFalsy(mtag.Get("optional"))
+ required := !isStringFalsy(mtag.Get("required"))
+ choices := mtag.GetMany("choice")
+ hidden := !isStringFalsy(mtag.Get("hidden"))
+
+ option := &Option{
+ Description: description,
+ ShortName: short,
+ LongName: longname,
+ Default: def,
+ EnvDefaultKey: mtag.Get("env"),
+ EnvDefaultDelim: mtag.Get("env-delim"),
+ OptionalArgument: optional,
+ OptionalValue: optionalValue,
+ Required: required,
+ ValueName: valueName,
+ DefaultMask: defaultMask,
+ Choices: choices,
+ Hidden: hidden,
+
+ group: g,
+
+ field: field,
+ value: realval.Field(i),
+ tag: mtag,
+ }
+
+ if option.isBool() && option.Default != nil {
+ return newErrorf(ErrInvalidTag,
+ "boolean flag `%s' may not have default values, they always default to `false' and can only be turned on",
+ option.shortAndLongName())
+ }
+
+ g.options = append(g.options, option)
+ }
+
+ return nil
+}
+
+func (g *Group) checkForDuplicateFlags() *Error {
+ shortNames := make(map[rune]*Option)
+ longNames := make(map[string]*Option)
+
+ var duplicateError *Error
+
+ g.eachGroup(func(g *Group) {
+ for _, option := range g.options {
+ if option.LongName != "" {
+ longName := option.LongNameWithNamespace()
+
+ if otherOption, ok := longNames[longName]; ok {
+ duplicateError = newErrorf(ErrDuplicatedFlag, "option `%s' uses the same long name as option `%s'", option, otherOption)
+ return
+ }
+ longNames[longName] = option
+ }
+ if option.ShortName != 0 {
+ if otherOption, ok := shortNames[option.ShortName]; ok {
+ duplicateError = newErrorf(ErrDuplicatedFlag, "option `%s' uses the same short name as option `%s'", option, otherOption)
+ return
+ }
+ shortNames[option.ShortName] = option
+ }
+ }
+ })
+
+ return duplicateError
+}
+
+func (g *Group) scanSubGroupHandler(realval reflect.Value, sfield *reflect.StructField) (bool, error) {
+ mtag := newMultiTag(string(sfield.Tag))
+
+ if err := mtag.Parse(); err != nil {
+ return true, err
+ }
+
+ subgroup := mtag.Get("group")
+
+ if len(subgroup) != 0 {
+ var ptrval reflect.Value
+
+ if realval.Kind() == reflect.Ptr {
+ ptrval = realval
+
+ if ptrval.IsNil() {
+ ptrval.Set(reflect.New(ptrval.Type()))
+ }
+ } else {
+ ptrval = realval.Addr()
+ }
+
+ description := mtag.Get("description")
+
+ group, err := g.AddGroup(subgroup, description, ptrval.Interface())
+
+ if err != nil {
+ return true, err
+ }
+
+ group.Namespace = mtag.Get("namespace")
+ group.Hidden = mtag.Get("hidden") != ""
+
+ return true, nil
+ }
+
+ return false, nil
+}
+
+func (g *Group) scanType(handler scanHandler) error {
+ // Get all the public fields in the data struct
+ ptrval := reflect.ValueOf(g.data)
+
+ if ptrval.Type().Kind() != reflect.Ptr {
+ panic(ErrNotPointerToStruct)
+ }
+
+ stype := ptrval.Type().Elem()
+
+ if stype.Kind() != reflect.Struct {
+ panic(ErrNotPointerToStruct)
+ }
+
+ realval := reflect.Indirect(ptrval)
+
+ if err := g.scanStruct(realval, nil, handler); err != nil {
+ return err
+ }
+
+ if err := g.checkForDuplicateFlags(); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (g *Group) scan() error {
+ return g.scanType(g.scanSubGroupHandler)
+}
+
+func (g *Group) groupByName(name string) *Group {
+ if len(name) == 0 {
+ return g
+ }
+
+ return g.Find(name)
+}
diff --git a/vendor/github.com/jessevdk/go-flags/help.go b/vendor/github.com/jessevdk/go-flags/help.go
new file mode 100644
index 0000000..d380305
--- /dev/null
+++ b/vendor/github.com/jessevdk/go-flags/help.go
@@ -0,0 +1,491 @@
+// Copyright 2012 Jesse van den Kieboom. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package flags
+
+import (
+ "bufio"
+ "bytes"
+ "fmt"
+ "io"
+ "runtime"
+ "strings"
+ "unicode/utf8"
+)
+
+type alignmentInfo struct {
+ maxLongLen int
+ hasShort bool
+ hasValueName bool
+ terminalColumns int
+ indent bool
+}
+
+const (
+ paddingBeforeOption = 2
+ distanceBetweenOptionAndDescription = 2
+)
+
+func (a *alignmentInfo) descriptionStart() int {
+ ret := a.maxLongLen + distanceBetweenOptionAndDescription
+
+ if a.hasShort {
+ ret += 2
+ }
+
+ if a.maxLongLen > 0 {
+ ret += 4
+ }
+
+ if a.hasValueName {
+ ret += 3
+ }
+
+ return ret
+}
+
+func (a *alignmentInfo) updateLen(name string, indent bool) {
+ l := utf8.RuneCountInString(name)
+
+ if indent {
+ l = l + 4
+ }
+
+ if l > a.maxLongLen {
+ a.maxLongLen = l
+ }
+}
+
+func (p *Parser) getAlignmentInfo() alignmentInfo {
+ ret := alignmentInfo{
+ maxLongLen: 0,
+ hasShort: false,
+ hasValueName: false,
+ terminalColumns: getTerminalColumns(),
+ }
+
+ if ret.terminalColumns <= 0 {
+ ret.terminalColumns = 80
+ }
+
+ var prevcmd *Command
+
+ p.eachActiveGroup(func(c *Command, grp *Group) {
+ if c != prevcmd {
+ for _, arg := range c.args {
+ ret.updateLen(arg.Name, c != p.Command)
+ }
+ }
+
+ for _, info := range grp.options {
+ if !info.canCli() {
+ continue
+ }
+
+ if info.ShortName != 0 {
+ ret.hasShort = true
+ }
+
+ if len(info.ValueName) > 0 {
+ ret.hasValueName = true
+ }
+
+ l := info.LongNameWithNamespace() + info.ValueName
+
+ if len(info.Choices) != 0 {
+ l += "[" + strings.Join(info.Choices, "|") + "]"
+ }
+
+ ret.updateLen(l, c != p.Command)
+ }
+ })
+
+ return ret
+}
+
+func wrapText(s string, l int, prefix string) string {
+ var ret string
+
+ if l < 10 {
+ l = 10
+ }
+
+ // Basic text wrapping of s at spaces to fit in l
+ lines := strings.Split(s, "\n")
+
+ for _, line := range lines {
+ var retline string
+
+ line = strings.TrimSpace(line)
+
+ for len(line) > l {
+ // Try to split on space
+ suffix := ""
+
+ pos := strings.LastIndex(line[:l], " ")
+
+ if pos < 0 {
+ pos = l - 1
+ suffix = "-\n"
+ }
+
+ if len(retline) != 0 {
+ retline += "\n" + prefix
+ }
+
+ retline += strings.TrimSpace(line[:pos]) + suffix
+ line = strings.TrimSpace(line[pos:])
+ }
+
+ if len(line) > 0 {
+ if len(retline) != 0 {
+ retline += "\n" + prefix
+ }
+
+ retline += line
+ }
+
+ if len(ret) > 0 {
+ ret += "\n"
+
+ if len(retline) > 0 {
+ ret += prefix
+ }
+ }
+
+ ret += retline
+ }
+
+ return ret
+}
+
+func (p *Parser) writeHelpOption(writer *bufio.Writer, option *Option, info alignmentInfo) {
+ line := &bytes.Buffer{}
+
+ prefix := paddingBeforeOption
+
+ if info.indent {
+ prefix += 4
+ }
+
+ if option.Hidden {
+ return
+ }
+
+ line.WriteString(strings.Repeat(" ", prefix))
+
+ if option.ShortName != 0 {
+ line.WriteRune(defaultShortOptDelimiter)
+ line.WriteRune(option.ShortName)
+ } else if info.hasShort {
+ line.WriteString(" ")
+ }
+
+ descstart := info.descriptionStart() + paddingBeforeOption
+
+ if len(option.LongName) > 0 {
+ if option.ShortName != 0 {
+ line.WriteString(", ")
+ } else if info.hasShort {
+ line.WriteString(" ")
+ }
+
+ line.WriteString(defaultLongOptDelimiter)
+ line.WriteString(option.LongNameWithNamespace())
+ }
+
+ if option.canArgument() {
+ line.WriteRune(defaultNameArgDelimiter)
+
+ if len(option.ValueName) > 0 {
+ line.WriteString(option.ValueName)
+ }
+
+ if len(option.Choices) > 0 {
+ line.WriteString("[" + strings.Join(option.Choices, "|") + "]")
+ }
+ }
+
+ written := line.Len()
+ line.WriteTo(writer)
+
+ if option.Description != "" {
+ dw := descstart - written
+ writer.WriteString(strings.Repeat(" ", dw))
+
+ var def string
+
+ if len(option.DefaultMask) != 0 {
+ if option.DefaultMask != "-" {
+ def = option.DefaultMask
+ }
+ } else {
+ def = option.defaultLiteral
+ }
+
+ var envDef string
+ if option.EnvDefaultKey != "" {
+ var envPrintable string
+ if runtime.GOOS == "windows" {
+ envPrintable = "%" + option.EnvDefaultKey + "%"
+ } else {
+ envPrintable = "$" + option.EnvDefaultKey
+ }
+ envDef = fmt.Sprintf(" [%s]", envPrintable)
+ }
+
+ var desc string
+
+ if def != "" {
+ desc = fmt.Sprintf("%s (default: %v)%s", option.Description, def, envDef)
+ } else {
+ desc = option.Description + envDef
+ }
+
+ writer.WriteString(wrapText(desc,
+ info.terminalColumns-descstart,
+ strings.Repeat(" ", descstart)))
+ }
+
+ writer.WriteString("\n")
+}
+
+func maxCommandLength(s []*Command) int {
+ if len(s) == 0 {
+ return 0
+ }
+
+ ret := len(s[0].Name)
+
+ for _, v := range s[1:] {
+ l := len(v.Name)
+
+ if l > ret {
+ ret = l
+ }
+ }
+
+ return ret
+}
+
+// WriteHelp writes a help message containing all the possible options and
+// their descriptions to the provided writer. Note that the HelpFlag parser
+// option provides a convenient way to add a -h/--help option group to the
+// command line parser which will automatically show the help messages using
+// this method.
+func (p *Parser) WriteHelp(writer io.Writer) {
+ if writer == nil {
+ return
+ }
+
+ wr := bufio.NewWriter(writer)
+ aligninfo := p.getAlignmentInfo()
+
+ cmd := p.Command
+
+ for cmd.Active != nil {
+ cmd = cmd.Active
+ }
+
+ if p.Name != "" {
+ wr.WriteString("Usage:\n")
+ wr.WriteString(" ")
+
+ allcmd := p.Command
+
+ for allcmd != nil {
+ var usage string
+
+ if allcmd == p.Command {
+ if len(p.Usage) != 0 {
+ usage = p.Usage
+ } else if p.Options&HelpFlag != 0 {
+ usage = "[OPTIONS]"
+ }
+ } else if us, ok := allcmd.data.(Usage); ok {
+ usage = us.Usage()
+ } else if allcmd.hasCliOptions() {
+ usage = fmt.Sprintf("[%s-OPTIONS]", allcmd.Name)
+ }
+
+ if len(usage) != 0 {
+ fmt.Fprintf(wr, " %s %s", allcmd.Name, usage)
+ } else {
+ fmt.Fprintf(wr, " %s", allcmd.Name)
+ }
+
+ if len(allcmd.args) > 0 {
+ fmt.Fprintf(wr, " ")
+ }
+
+ for i, arg := range allcmd.args {
+ if i != 0 {
+ fmt.Fprintf(wr, " ")
+ }
+
+ name := arg.Name
+
+ if arg.isRemaining() {
+ name = name + "..."
+ }
+
+ if !allcmd.ArgsRequired {
+ fmt.Fprintf(wr, "[%s]", name)
+ } else {
+ fmt.Fprintf(wr, "%s", name)
+ }
+ }
+
+ if allcmd.Active == nil && len(allcmd.commands) > 0 {
+ var co, cc string
+
+ if allcmd.SubcommandsOptional {
+ co, cc = "[", "]"
+ } else {
+ co, cc = "<", ">"
+ }
+
+ visibleCommands := allcmd.visibleCommands()
+
+ if len(visibleCommands) > 3 {
+ fmt.Fprintf(wr, " %scommand%s", co, cc)
+ } else {
+ subcommands := allcmd.sortedVisibleCommands()
+ names := make([]string, len(subcommands))
+
+ for i, subc := range subcommands {
+ names[i] = subc.Name
+ }
+
+ fmt.Fprintf(wr, " %s%s%s", co, strings.Join(names, " | "), cc)
+ }
+ }
+
+ allcmd = allcmd.Active
+ }
+
+ fmt.Fprintln(wr)
+
+ if len(cmd.LongDescription) != 0 {
+ fmt.Fprintln(wr)
+
+ t := wrapText(cmd.LongDescription,
+ aligninfo.terminalColumns,
+ "")
+
+ fmt.Fprintln(wr, t)
+ }
+ }
+
+ c := p.Command
+
+ for c != nil {
+ printcmd := c != p.Command
+
+ c.eachGroup(func(grp *Group) {
+ first := true
+
+ // Skip built-in help group for all commands except the top-level
+ // parser
+ if grp.Hidden || (grp.isBuiltinHelp && c != p.Command) {
+ return
+ }
+
+ for _, info := range grp.options {
+ if !info.canCli() || info.Hidden {
+ continue
+ }
+
+ if printcmd {
+ fmt.Fprintf(wr, "\n[%s command options]\n", c.Name)
+ aligninfo.indent = true
+ printcmd = false
+ }
+
+ if first && cmd.Group != grp {
+ fmt.Fprintln(wr)
+
+ if aligninfo.indent {
+ wr.WriteString(" ")
+ }
+
+ fmt.Fprintf(wr, "%s:\n", grp.ShortDescription)
+ first = false
+ }
+
+ p.writeHelpOption(wr, info, aligninfo)
+ }
+ })
+
+ var args []*Arg
+ for _, arg := range c.args {
+ if arg.Description != "" {
+ args = append(args, arg)
+ }
+ }
+
+ if len(args) > 0 {
+ if c == p.Command {
+ fmt.Fprintf(wr, "\nArguments:\n")
+ } else {
+ fmt.Fprintf(wr, "\n[%s command arguments]\n", c.Name)
+ }
+
+ descStart := aligninfo.descriptionStart() + paddingBeforeOption
+
+ for _, arg := range args {
+ argPrefix := strings.Repeat(" ", paddingBeforeOption)
+ argPrefix += arg.Name
+
+ if len(arg.Description) > 0 {
+ argPrefix += ":"
+ wr.WriteString(argPrefix)
+
+ // Space between "arg:" and the description start
+ descPadding := strings.Repeat(" ", descStart-len(argPrefix))
+ // How much space the description gets before wrapping
+ descWidth := aligninfo.terminalColumns - 1 - descStart
+ // Whitespace to which we can indent new description lines
+ descPrefix := strings.Repeat(" ", descStart)
+
+ wr.WriteString(descPadding)
+ wr.WriteString(wrapText(arg.Description, descWidth, descPrefix))
+ } else {
+ wr.WriteString(argPrefix)
+ }
+
+ fmt.Fprintln(wr)
+ }
+ }
+
+ c = c.Active
+ }
+
+ scommands := cmd.sortedVisibleCommands()
+
+ if len(scommands) > 0 {
+ maxnamelen := maxCommandLength(scommands)
+
+ fmt.Fprintln(wr)
+ fmt.Fprintln(wr, "Available commands:")
+
+ for _, c := range scommands {
+ fmt.Fprintf(wr, " %s", c.Name)
+
+ if len(c.ShortDescription) > 0 {
+ pad := strings.Repeat(" ", maxnamelen-len(c.Name))
+ fmt.Fprintf(wr, "%s %s", pad, c.ShortDescription)
+
+ if len(c.Aliases) > 0 {
+ fmt.Fprintf(wr, " (aliases: %s)", strings.Join(c.Aliases, ", "))
+ }
+
+ }
+
+ fmt.Fprintln(wr)
+ }
+ }
+
+ wr.Flush()
+}
diff --git a/vendor/github.com/jessevdk/go-flags/ini.go b/vendor/github.com/jessevdk/go-flags/ini.go
new file mode 100644
index 0000000..e714d3d
--- /dev/null
+++ b/vendor/github.com/jessevdk/go-flags/ini.go
@@ -0,0 +1,597 @@
+package flags
+
+import (
+ "bufio"
+ "fmt"
+ "io"
+ "os"
+ "reflect"
+ "sort"
+ "strconv"
+ "strings"
+)
+
+// IniError contains location information on where an error occurred.
+type IniError struct {
+ // The error message.
+ Message string
+
+ // The filename of the file in which the error occurred.
+ File string
+
+ // The line number at which the error occurred.
+ LineNumber uint
+}
+
+// Error provides a "file:line: message" formatted message of the ini error.
+func (x *IniError) Error() string {
+ return fmt.Sprintf(
+ "%s:%d: %s",
+ x.File,
+ x.LineNumber,
+ x.Message,
+ )
+}
+
+// IniOptions for writing
+type IniOptions uint
+
+const (
+ // IniNone indicates no options.
+ IniNone IniOptions = 0
+
+ // IniIncludeDefaults indicates that default values should be written.
+ IniIncludeDefaults = 1 << iota
+
+ // IniCommentDefaults indicates that if IniIncludeDefaults is used
+ // options with default values are written but commented out.
+ IniCommentDefaults
+
+ // IniIncludeComments indicates that comments containing the description
+ // of an option should be written.
+ IniIncludeComments
+
+ // IniDefault provides a default set of options.
+ IniDefault = IniIncludeComments
+)
+
+// IniParser is a utility to read and write flags options from and to ini
+// formatted strings.
+type IniParser struct {
+ ParseAsDefaults bool // override default flags
+
+ parser *Parser
+}
+
+type iniValue struct {
+ Name string
+ Value string
+ Quoted bool
+ LineNumber uint
+}
+
+type iniSection []iniValue
+
+type ini struct {
+ File string
+ Sections map[string]iniSection
+}
+
+// NewIniParser creates a new ini parser for a given Parser.
+func NewIniParser(p *Parser) *IniParser {
+ return &IniParser{
+ parser: p,
+ }
+}
+
+// IniParse is a convenience function to parse command line options with default
+// settings from an ini formatted file. The provided data is a pointer to a struct
+// representing the default option group (named "Application Options"). For
+// more control, use flags.NewParser.
+func IniParse(filename string, data interface{}) error {
+ p := NewParser(data, Default)
+
+ return NewIniParser(p).ParseFile(filename)
+}
+
+// ParseFile parses flags from an ini formatted file. See Parse for more
+// information on the ini file format. The returned errors can be of the type
+// flags.Error or flags.IniError.
+func (i *IniParser) ParseFile(filename string) error {
+ ini, err := readIniFromFile(filename)
+
+ if err != nil {
+ return err
+ }
+
+ return i.parse(ini)
+}
+
+// Parse parses flags from an ini format. You can use ParseFile as a
+// convenience function to parse from a filename instead of a general
+// io.Reader.
+//
+// The format of the ini file is as follows:
+//
+// [Option group name]
+// option = value
+//
+// Each section in the ini file represents an option group or command in the
+// flags parser. The default flags parser option group (i.e. when using
+// flags.Parse) is named 'Application Options'. The ini option name is matched
+// in the following order:
+//
+// 1. Compared to the ini-name tag on the option struct field (if present)
+// 2. Compared to the struct field name
+// 3. Compared to the option long name (if present)
+// 4. Compared to the option short name (if present)
+//
+// Sections for nested groups and commands can be addressed using a dot `.'
+// namespacing notation (i.e [subcommand.Options]). Group section names are
+// matched case insensitive.
+//
+// The returned errors can be of the type flags.Error or flags.IniError.
+func (i *IniParser) Parse(reader io.Reader) error {
+ ini, err := readIni(reader, "")
+
+ if err != nil {
+ return err
+ }
+
+ return i.parse(ini)
+}
+
+// WriteFile writes the flags as ini format into a file. See Write
+// for more information. The returned error occurs when the specified file
+// could not be opened for writing.
+func (i *IniParser) WriteFile(filename string, options IniOptions) error {
+ return writeIniToFile(i, filename, options)
+}
+
+// Write writes the current values of all the flags to an ini format.
+// See Parse for more information on the ini file format. You typically
+// call this only after settings have been parsed since the default values of each
+// option are stored just before parsing the flags (this is only relevant when
+// IniIncludeDefaults is _not_ set in options).
+func (i *IniParser) Write(writer io.Writer, options IniOptions) {
+ writeIni(i, writer, options)
+}
+
+func readFullLine(reader *bufio.Reader) (string, error) {
+ var line []byte
+
+ for {
+ l, more, err := reader.ReadLine()
+
+ if err != nil {
+ return "", err
+ }
+
+ if line == nil && !more {
+ return string(l), nil
+ }
+
+ line = append(line, l...)
+
+ if !more {
+ break
+ }
+ }
+
+ return string(line), nil
+}
+
+func optionIniName(option *Option) string {
+ name := option.tag.Get("_read-ini-name")
+
+ if len(name) != 0 {
+ return name
+ }
+
+ name = option.tag.Get("ini-name")
+
+ if len(name) != 0 {
+ return name
+ }
+
+ return option.field.Name
+}
+
+func writeGroupIni(cmd *Command, group *Group, namespace string, writer io.Writer, options IniOptions) {
+ var sname string
+
+ if len(namespace) != 0 {
+ sname = namespace
+ }
+
+ if cmd.Group != group && len(group.ShortDescription) != 0 {
+ if len(sname) != 0 {
+ sname += "."
+ }
+
+ sname += group.ShortDescription
+ }
+
+ sectionwritten := false
+ comments := (options & IniIncludeComments) != IniNone
+
+ for _, option := range group.options {
+ if option.isFunc() || option.Hidden {
+ continue
+ }
+
+ if len(option.tag.Get("no-ini")) != 0 {
+ continue
+ }
+
+ val := option.value
+
+ if (options&IniIncludeDefaults) == IniNone && option.valueIsDefault() {
+ continue
+ }
+
+ if !sectionwritten {
+ fmt.Fprintf(writer, "[%s]\n", sname)
+ sectionwritten = true
+ }
+
+ if comments && len(option.Description) != 0 {
+ fmt.Fprintf(writer, "; %s\n", option.Description)
+ }
+
+ oname := optionIniName(option)
+
+ commentOption := (options&(IniIncludeDefaults|IniCommentDefaults)) == IniIncludeDefaults|IniCommentDefaults && option.valueIsDefault()
+
+ kind := val.Type().Kind()
+ switch kind {
+ case reflect.Slice:
+ kind = val.Type().Elem().Kind()
+
+ if val.Len() == 0 {
+ writeOption(writer, oname, kind, "", "", true, option.iniQuote)
+ } else {
+ for idx := 0; idx < val.Len(); idx++ {
+ v, _ := convertToString(val.Index(idx), option.tag)
+
+ writeOption(writer, oname, kind, "", v, commentOption, option.iniQuote)
+ }
+ }
+ case reflect.Map:
+ kind = val.Type().Elem().Kind()
+
+ if val.Len() == 0 {
+ writeOption(writer, oname, kind, "", "", true, option.iniQuote)
+ } else {
+ mkeys := val.MapKeys()
+ keys := make([]string, len(val.MapKeys()))
+ kkmap := make(map[string]reflect.Value)
+
+ for i, k := range mkeys {
+ keys[i], _ = convertToString(k, option.tag)
+ kkmap[keys[i]] = k
+ }
+
+ sort.Strings(keys)
+
+ for _, k := range keys {
+ v, _ := convertToString(val.MapIndex(kkmap[k]), option.tag)
+
+ writeOption(writer, oname, kind, k, v, commentOption, option.iniQuote)
+ }
+ }
+ default:
+ v, _ := convertToString(val, option.tag)
+
+ writeOption(writer, oname, kind, "", v, commentOption, option.iniQuote)
+ }
+
+ if comments {
+ fmt.Fprintln(writer)
+ }
+ }
+
+ if sectionwritten && !comments {
+ fmt.Fprintln(writer)
+ }
+}
+
+func writeOption(writer io.Writer, optionName string, optionType reflect.Kind, optionKey string, optionValue string, commentOption bool, forceQuote bool) {
+ if forceQuote || (optionType == reflect.String && !isPrint(optionValue)) {
+ optionValue = strconv.Quote(optionValue)
+ }
+
+ comment := ""
+ if commentOption {
+ comment = "; "
+ }
+
+ fmt.Fprintf(writer, "%s%s =", comment, optionName)
+
+ if optionKey != "" {
+ fmt.Fprintf(writer, " %s:%s", optionKey, optionValue)
+ } else if optionValue != "" {
+ fmt.Fprintf(writer, " %s", optionValue)
+ }
+
+ fmt.Fprintln(writer)
+}
+
+func writeCommandIni(command *Command, namespace string, writer io.Writer, options IniOptions) {
+ command.eachGroup(func(group *Group) {
+ if !group.Hidden {
+ writeGroupIni(command, group, namespace, writer, options)
+ }
+ })
+
+ for _, c := range command.commands {
+ var nns string
+
+ if c.Hidden {
+ continue
+ }
+
+ if len(namespace) != 0 {
+ nns = c.Name + "." + nns
+ } else {
+ nns = c.Name
+ }
+
+ writeCommandIni(c, nns, writer, options)
+ }
+}
+
+func writeIni(parser *IniParser, writer io.Writer, options IniOptions) {
+ writeCommandIni(parser.parser.Command, "", writer, options)
+}
+
+func writeIniToFile(parser *IniParser, filename string, options IniOptions) error {
+ file, err := os.Create(filename)
+
+ if err != nil {
+ return err
+ }
+
+ defer file.Close()
+
+ writeIni(parser, file, options)
+
+ return nil
+}
+
+func readIniFromFile(filename string) (*ini, error) {
+ file, err := os.Open(filename)
+
+ if err != nil {
+ return nil, err
+ }
+
+ defer file.Close()
+
+ return readIni(file, filename)
+}
+
+func readIni(contents io.Reader, filename string) (*ini, error) {
+ ret := &ini{
+ File: filename,
+ Sections: make(map[string]iniSection),
+ }
+
+ reader := bufio.NewReader(contents)
+
+ // Empty global section
+ section := make(iniSection, 0, 10)
+ sectionname := ""
+
+ ret.Sections[sectionname] = section
+
+ var lineno uint
+
+ for {
+ line, err := readFullLine(reader)
+
+ if err == io.EOF {
+ break
+ } else if err != nil {
+ return nil, err
+ }
+
+ lineno++
+ line = strings.TrimSpace(line)
+
+ // Skip empty lines and lines starting with ; (comments)
+ if len(line) == 0 || line[0] == ';' || line[0] == '#' {
+ continue
+ }
+
+ if line[0] == '[' {
+ if line[0] != '[' || line[len(line)-1] != ']' {
+ return nil, &IniError{
+ Message: "malformed section header",
+ File: filename,
+ LineNumber: lineno,
+ }
+ }
+
+ name := strings.TrimSpace(line[1 : len(line)-1])
+
+ if len(name) == 0 {
+ return nil, &IniError{
+ Message: "empty section name",
+ File: filename,
+ LineNumber: lineno,
+ }
+ }
+
+ sectionname = name
+ section = ret.Sections[name]
+
+ if section == nil {
+ section = make(iniSection, 0, 10)
+ ret.Sections[name] = section
+ }
+
+ continue
+ }
+
+ // Parse option here
+ keyval := strings.SplitN(line, "=", 2)
+
+ if len(keyval) != 2 {
+ return nil, &IniError{
+ Message: fmt.Sprintf("malformed key=value (%s)", line),
+ File: filename,
+ LineNumber: lineno,
+ }
+ }
+
+ name := strings.TrimSpace(keyval[0])
+ value := strings.TrimSpace(keyval[1])
+ quoted := false
+
+ if len(value) != 0 && value[0] == '"' {
+ if v, err := strconv.Unquote(value); err == nil {
+ value = v
+
+ quoted = true
+ } else {
+ return nil, &IniError{
+ Message: err.Error(),
+ File: filename,
+ LineNumber: lineno,
+ }
+ }
+ }
+
+ section = append(section, iniValue{
+ Name: name,
+ Value: value,
+ Quoted: quoted,
+ LineNumber: lineno,
+ })
+
+ ret.Sections[sectionname] = section
+ }
+
+ return ret, nil
+}
+
+func (i *IniParser) matchingGroups(name string) []*Group {
+ if len(name) == 0 {
+ var ret []*Group
+
+ i.parser.eachGroup(func(g *Group) {
+ ret = append(ret, g)
+ })
+
+ return ret
+ }
+
+ g := i.parser.groupByName(name)
+
+ if g != nil {
+ return []*Group{g}
+ }
+
+ return nil
+}
+
+func (i *IniParser) parse(ini *ini) error {
+ p := i.parser
+
+ var quotesLookup = make(map[*Option]bool)
+
+ for name, section := range ini.Sections {
+ groups := i.matchingGroups(name)
+
+ if len(groups) == 0 {
+ return newErrorf(ErrUnknownGroup, "could not find option group `%s'", name)
+ }
+
+ for _, inival := range section {
+ var opt *Option
+
+ for _, group := range groups {
+ opt = group.optionByName(inival.Name, func(o *Option, n string) bool {
+ return strings.ToLower(o.tag.Get("ini-name")) == strings.ToLower(n)
+ })
+
+ if opt != nil && len(opt.tag.Get("no-ini")) != 0 {
+ opt = nil
+ }
+
+ if opt != nil {
+ break
+ }
+ }
+
+ if opt == nil {
+ if (p.Options & IgnoreUnknown) == None {
+ return &IniError{
+ Message: fmt.Sprintf("unknown option: %s", inival.Name),
+ File: ini.File,
+ LineNumber: inival.LineNumber,
+ }
+ }
+
+ continue
+ }
+
+ // ini value is ignored if override is set and
+ // value was previously set from non default
+ if i.ParseAsDefaults && !opt.isSetDefault {
+ continue
+ }
+
+ pval := &inival.Value
+
+ if !opt.canArgument() && len(inival.Value) == 0 {
+ pval = nil
+ } else {
+ if opt.value.Type().Kind() == reflect.Map {
+ parts := strings.SplitN(inival.Value, ":", 2)
+
+ // only handle unquoting
+ if len(parts) == 2 && parts[1][0] == '"' {
+ if v, err := strconv.Unquote(parts[1]); err == nil {
+ parts[1] = v
+
+ inival.Quoted = true
+ } else {
+ return &IniError{
+ Message: err.Error(),
+ File: ini.File,
+ LineNumber: inival.LineNumber,
+ }
+ }
+
+ s := parts[0] + ":" + parts[1]
+
+ pval = &s
+ }
+ }
+ }
+
+ if err := opt.set(pval); err != nil {
+ return &IniError{
+ Message: err.Error(),
+ File: ini.File,
+ LineNumber: inival.LineNumber,
+ }
+ }
+
+ // either all INI values are quoted or only values who need quoting
+ if _, ok := quotesLookup[opt]; !inival.Quoted || !ok {
+ quotesLookup[opt] = inival.Quoted
+ }
+
+ opt.tag.Set("_read-ini-name", inival.Name)
+ }
+ }
+
+ for opt, quoted := range quotesLookup {
+ opt.iniQuote = quoted
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/jessevdk/go-flags/man.go b/vendor/github.com/jessevdk/go-flags/man.go
new file mode 100644
index 0000000..0cb114e
--- /dev/null
+++ b/vendor/github.com/jessevdk/go-flags/man.go
@@ -0,0 +1,205 @@
+package flags
+
+import (
+ "fmt"
+ "io"
+ "runtime"
+ "strings"
+ "time"
+)
+
+func manQuote(s string) string {
+ return strings.Replace(s, "\\", "\\\\", -1)
+}
+
+func formatForMan(wr io.Writer, s string) {
+ for {
+ idx := strings.IndexRune(s, '`')
+
+ if idx < 0 {
+ fmt.Fprintf(wr, "%s", manQuote(s))
+ break
+ }
+
+ fmt.Fprintf(wr, "%s", manQuote(s[:idx]))
+
+ s = s[idx+1:]
+ idx = strings.IndexRune(s, '\'')
+
+ if idx < 0 {
+ fmt.Fprintf(wr, "%s", manQuote(s))
+ break
+ }
+
+ fmt.Fprintf(wr, "\\fB%s\\fP", manQuote(s[:idx]))
+ s = s[idx+1:]
+ }
+}
+
+func writeManPageOptions(wr io.Writer, grp *Group) {
+ grp.eachGroup(func(group *Group) {
+ if group.Hidden || len(group.options) == 0 {
+ return
+ }
+
+ // If the parent (grp) has any subgroups, display their descriptions as
+ // subsection headers similar to the output of --help.
+ if group.ShortDescription != "" && len(grp.groups) > 0 {
+ fmt.Fprintf(wr, ".SS %s\n", group.ShortDescription)
+
+ if group.LongDescription != "" {
+ formatForMan(wr, group.LongDescription)
+ fmt.Fprintln(wr, "")
+ }
+ }
+
+ for _, opt := range group.options {
+ if !opt.canCli() || opt.Hidden {
+ continue
+ }
+
+ fmt.Fprintln(wr, ".TP")
+ fmt.Fprintf(wr, "\\fB")
+
+ if opt.ShortName != 0 {
+ fmt.Fprintf(wr, "\\fB\\-%c\\fR", opt.ShortName)
+ }
+
+ if len(opt.LongName) != 0 {
+ if opt.ShortName != 0 {
+ fmt.Fprintf(wr, ", ")
+ }
+
+ fmt.Fprintf(wr, "\\fB\\-\\-%s\\fR", manQuote(opt.LongNameWithNamespace()))
+ }
+
+ if len(opt.ValueName) != 0 || opt.OptionalArgument {
+ if opt.OptionalArgument {
+ fmt.Fprintf(wr, " [\\fI%s=%s\\fR]", manQuote(opt.ValueName), manQuote(strings.Join(quoteV(opt.OptionalValue), ", ")))
+ } else {
+ fmt.Fprintf(wr, " \\fI%s\\fR", manQuote(opt.ValueName))
+ }
+ }
+
+ if len(opt.Default) != 0 {
+ fmt.Fprintf(wr, " <default: \\fI%s\\fR>", manQuote(strings.Join(quoteV(opt.Default), ", ")))
+ } else if len(opt.EnvDefaultKey) != 0 {
+ if runtime.GOOS == "windows" {
+ fmt.Fprintf(wr, " <default: \\fI%%%s%%\\fR>", manQuote(opt.EnvDefaultKey))
+ } else {
+ fmt.Fprintf(wr, " <default: \\fI$%s\\fR>", manQuote(opt.EnvDefaultKey))
+ }
+ }
+
+ if opt.Required {
+ fmt.Fprintf(wr, " (\\fIrequired\\fR)")
+ }
+
+ fmt.Fprintln(wr, "\\fP")
+
+ if len(opt.Description) != 0 {
+ formatForMan(wr, opt.Description)
+ fmt.Fprintln(wr, "")
+ }
+ }
+ })
+}
+
+func writeManPageSubcommands(wr io.Writer, name string, root *Command) {
+ commands := root.sortedVisibleCommands()
+
+ for _, c := range commands {
+ var nn string
+
+ if c.Hidden {
+ continue
+ }
+
+ if len(name) != 0 {
+ nn = name + " " + c.Name
+ } else {
+ nn = c.Name
+ }
+
+ writeManPageCommand(wr, nn, root, c)
+ }
+}
+
+func writeManPageCommand(wr io.Writer, name string, root *Command, command *Command) {
+ fmt.Fprintf(wr, ".SS %s\n", name)
+ fmt.Fprintln(wr, command.ShortDescription)
+
+ if len(command.LongDescription) > 0 {
+ fmt.Fprintln(wr, "")
+
+ cmdstart := fmt.Sprintf("The %s command", manQuote(command.Name))
+
+ if strings.HasPrefix(command.LongDescription, cmdstart) {
+ fmt.Fprintf(wr, "The \\fI%s\\fP command", manQuote(command.Name))
+
+ formatForMan(wr, command.LongDescription[len(cmdstart):])
+ fmt.Fprintln(wr, "")
+ } else {
+ formatForMan(wr, command.LongDescription)
+ fmt.Fprintln(wr, "")
+ }
+ }
+
+ var usage string
+ if us, ok := command.data.(Usage); ok {
+ usage = us.Usage()
+ } else if command.hasCliOptions() {
+ usage = fmt.Sprintf("[%s-OPTIONS]", command.Name)
+ }
+
+ var pre string
+ if root.hasCliOptions() {
+ pre = fmt.Sprintf("%s [OPTIONS] %s", root.Name, command.Name)
+ } else {
+ pre = fmt.Sprintf("%s %s", root.Name, command.Name)
+ }
+
+ if len(usage) > 0 {
+ fmt.Fprintf(wr, "\n\\fBUsage\\fP: %s %s\n.TP\n", manQuote(pre), manQuote(usage))
+ }
+
+ if len(command.Aliases) > 0 {
+ fmt.Fprintf(wr, "\n\\fBAliases\\fP: %s\n\n", manQuote(strings.Join(command.Aliases, ", ")))
+ }
+
+ writeManPageOptions(wr, command.Group)
+ writeManPageSubcommands(wr, name, command)
+}
+
+// WriteManPage writes a basic man page in groff format to the specified
+// writer.
+func (p *Parser) WriteManPage(wr io.Writer) {
+ t := time.Now()
+
+ fmt.Fprintf(wr, ".TH %s 1 \"%s\"\n", manQuote(p.Name), t.Format("2 January 2006"))
+ fmt.Fprintln(wr, ".SH NAME")
+ fmt.Fprintf(wr, "%s \\- %s\n", manQuote(p.Name), manQuote(p.ShortDescription))
+ fmt.Fprintln(wr, ".SH SYNOPSIS")
+
+ usage := p.Usage
+
+ if len(usage) == 0 {
+ usage = "[OPTIONS]"
+ }
+
+ fmt.Fprintf(wr, "\\fB%s\\fP %s\n", manQuote(p.Name), manQuote(usage))
+ fmt.Fprintln(wr, ".SH DESCRIPTION")
+
+ formatForMan(wr, p.LongDescription)
+ fmt.Fprintln(wr, "")
+
+ fmt.Fprintln(wr, ".SH OPTIONS")
+
+ writeManPageOptions(wr, p.Command.Group)
+
+ if len(p.visibleCommands()) > 0 {
+ fmt.Fprintln(wr, ".SH COMMANDS")
+
+ writeManPageSubcommands(wr, "", p.Command)
+ }
+}
diff --git a/vendor/github.com/jessevdk/go-flags/multitag.go b/vendor/github.com/jessevdk/go-flags/multitag.go
new file mode 100644
index 0000000..96bb1a3
--- /dev/null
+++ b/vendor/github.com/jessevdk/go-flags/multitag.go
@@ -0,0 +1,140 @@
+package flags
+
+import (
+ "strconv"
+)
+
+type multiTag struct {
+ value string
+ cache map[string][]string
+}
+
+func newMultiTag(v string) multiTag {
+ return multiTag{
+ value: v,
+ }
+}
+
+func (x *multiTag) scan() (map[string][]string, error) {
+ v := x.value
+
+ ret := make(map[string][]string)
+
+ // This is mostly copied from reflect.StructTag.Get
+ for v != "" {
+ i := 0
+
+ // Skip whitespace
+ for i < len(v) && v[i] == ' ' {
+ i++
+ }
+
+ v = v[i:]
+
+ if v == "" {
+ break
+ }
+
+ // Scan to colon to find key
+ i = 0
+
+ for i < len(v) && v[i] != ' ' && v[i] != ':' && v[i] != '"' {
+ i++
+ }
+
+ if i >= len(v) {
+ return nil, newErrorf(ErrTag, "expected `:' after key name, but got end of tag (in `%v`)", x.value)
+ }
+
+ if v[i] != ':' {
+ return nil, newErrorf(ErrTag, "expected `:' after key name, but got `%v' (in `%v`)", v[i], x.value)
+ }
+
+ if i+1 >= len(v) {
+ return nil, newErrorf(ErrTag, "expected `\"' to start tag value at end of tag (in `%v`)", x.value)
+ }
+
+ if v[i+1] != '"' {
+ return nil, newErrorf(ErrTag, "expected `\"' to start tag value, but got `%v' (in `%v`)", v[i+1], x.value)
+ }
+
+ name := v[:i]
+ v = v[i+1:]
+
+ // Scan quoted string to find value
+ i = 1
+
+ for i < len(v) && v[i] != '"' {
+ if v[i] == '\n' {
+ return nil, newErrorf(ErrTag, "unexpected newline in tag value `%v' (in `%v`)", name, x.value)
+ }
+
+ if v[i] == '\\' {
+ i++
+ }
+ i++
+ }
+
+ if i >= len(v) {
+ return nil, newErrorf(ErrTag, "expected end of tag value `\"' at end of tag (in `%v`)", x.value)
+ }
+
+ val, err := strconv.Unquote(v[:i+1])
+
+ if err != nil {
+ return nil, newErrorf(ErrTag, "Malformed value of tag `%v:%v` => %v (in `%v`)", name, v[:i+1], err, x.value)
+ }
+
+ v = v[i+1:]
+
+ ret[name] = append(ret[name], val)
+ }
+
+ return ret, nil
+}
+
+func (x *multiTag) Parse() error {
+ vals, err := x.scan()
+ x.cache = vals
+
+ return err
+}
+
+func (x *multiTag) cached() map[string][]string {
+ if x.cache == nil {
+ cache, _ := x.scan()
+
+ if cache == nil {
+ cache = make(map[string][]string)
+ }
+
+ x.cache = cache
+ }
+
+ return x.cache
+}
+
+func (x *multiTag) Get(key string) string {
+ c := x.cached()
+
+ if v, ok := c[key]; ok {
+ return v[len(v)-1]
+ }
+
+ return ""
+}
+
+func (x *multiTag) GetMany(key string) []string {
+ c := x.cached()
+ return c[key]
+}
+
+func (x *multiTag) Set(key string, value string) {
+ c := x.cached()
+ c[key] = []string{value}
+}
+
+func (x *multiTag) SetMany(key string, value []string) {
+ c := x.cached()
+ c[key] = value
+}
diff --git a/vendor/github.com/jessevdk/go-flags/option.go b/vendor/github.com/jessevdk/go-flags/option.go
new file mode 100644
index 0000000..5f85250
--- /dev/null
+++ b/vendor/github.com/jessevdk/go-flags/option.go
@@ -0,0 +1,459 @@
+package flags
+
+import (
+ "bytes"
+ "fmt"
+ "os"
+ "reflect"
+ "strings"
+ "unicode/utf8"
+)
+
+// Option flag information. Contains a description of the option, short and
+// long name as well as a default value and whether an argument for this
+// flag is optional.
+type Option struct {
+ // The description of the option flag. This description is shown
+ // automatically in the built-in help.
+ Description string
+
+ // The short name of the option (a single character). If not 0, the
+ // option flag can be 'activated' using -<ShortName>. Either ShortName
+ // or LongName needs to be non-empty.
+ ShortName rune
+
+ // The long name of the option. If not "", the option flag can be
+ // activated using --<LongName>. Either ShortName or LongName needs
+ // to be non-empty.
+ LongName string
+
+ // The default value of the option.
+ Default []string
+
+ // The optional environment default value key name.
+ EnvDefaultKey string
+
+ // The optional delimiter string for EnvDefaultKey values.
+ EnvDefaultDelim string
+
+ // If true, specifies that the argument to an option flag is optional.
+ // When no argument to the flag is specified on the command line, the
+ // value of OptionalValue will be set in the field this option represents.
+ // This is only valid for non-boolean options.
+ OptionalArgument bool
+
+ // The optional value of the option. The optional value is used when
+ // the option flag is marked as having an OptionalArgument. This means
+ // that when the flag is specified, but no option argument is given,
+ // the value of the field this option represents will be set to
+ // OptionalValue. This is only valid for non-boolean options.
+ OptionalValue []string
+
+ // If true, the option _must_ be specified on the command line. If the
+ // option is not specified, the parser will generate an ErrRequired type
+ // error.
+ Required bool
+
+ // A name for the value of an option shown in the Help as --flag [ValueName]
+ ValueName string
+
+ // A mask value to show in the help instead of the default value. This
+ // is useful for hiding sensitive information in the help, such as
+ // passwords.
+ DefaultMask string
+
+ // If non empty, only a certain set of values is allowed for an option.
+ Choices []string
+
+ // If true, the option is not displayed in the help or man page
+ Hidden bool
+
+ // The group which the option belongs to
+ group *Group
+
+ // The struct field which the option represents.
+ field reflect.StructField
+
+ // The struct field value which the option represents.
+ value reflect.Value
+
+ // Determines if the option will be always quoted in the INI output
+ iniQuote bool
+
+ tag multiTag
+ isSet bool
+ isSetDefault bool
+ preventDefault bool
+
+ defaultLiteral string
+}
+
+// LongNameWithNamespace returns the option's long name with the group namespaces
+// prepended by walking up the option's group tree. Namespaces and the long name
+// itself are separated by the parser's namespace delimiter. If the long name is
+// empty an empty string is returned.
+func (option *Option) LongNameWithNamespace() string {
+ if len(option.LongName) == 0 {
+ return ""
+ }
+
+ // fetch the namespace delimiter from the parser which is always at the
+ // end of the group hierarchy
+ namespaceDelimiter := ""
+ g := option.group
+
+ for {
+ if p, ok := g.parent.(*Parser); ok {
+ namespaceDelimiter = p.NamespaceDelimiter
+
+ break
+ }
+
+ switch i := g.parent.(type) {
+ case *Command:
+ g = i.Group
+ case *Group:
+ g = i
+ }
+ }
+
+ // concatenate long name with namespace
+ longName := option.LongName
+ g = option.group
+
+ for g != nil {
+ if g.Namespace != "" {
+ longName = g.Namespace + namespaceDelimiter + longName
+ }
+
+ switch i := g.parent.(type) {
+ case *Command:
+ g = i.Group
+ case *Group:
+ g = i
+ case *Parser:
+ g = nil
+ }
+ }
+
+ return longName
+}
+
+// String converts an option to a human friendly readable string describing the
+// option.
+func (option *Option) String() string {
+ var s string
+ var short string
+
+ if option.ShortName != 0 {
+ data := make([]byte, utf8.RuneLen(option.ShortName))
+ utf8.EncodeRune(data, option.ShortName)
+ short = string(data)
+
+ if len(option.LongName) != 0 {
+ s = fmt.Sprintf("%s%s, %s%s",
+ string(defaultShortOptDelimiter), short,
+ defaultLongOptDelimiter, option.LongNameWithNamespace())
+ } else {
+ s = fmt.Sprintf("%s%s", string(defaultShortOptDelimiter), short)
+ }
+ } else if len(option.LongName) != 0 {
+ s = fmt.Sprintf("%s%s", defaultLongOptDelimiter, option.LongNameWithNamespace())
+ }
+
+ return s
+}
+
+// Value returns the option value as an interface{}.
+func (option *Option) Value() interface{} {
+ return option.value.Interface()
+}
+
+// Field returns the reflect struct field of the option.
+func (option *Option) Field() reflect.StructField {
+ return option.field
+}
+
+// IsSet returns true if option has been set
+func (option *Option) IsSet() bool {
+ return option.isSet
+}
+
+// IsSetDefault returns true if option has been set via the default option tag
+func (option *Option) IsSetDefault() bool {
+ return option.isSetDefault
+}
+
+// Set the value of an option to the specified value. An error will be returned
+// if the specified value could not be converted to the corresponding option
+// value type.
+func (option *Option) set(value *string) error {
+ kind := option.value.Type().Kind()
+
+ if (kind == reflect.Map || kind == reflect.Slice) && !option.isSet {
+ option.empty()
+ }
+
+ option.isSet = true
+ option.preventDefault = true
+
+ if len(option.Choices) != 0 {
+ found := false
+
+ for _, choice := range option.Choices {
+ if choice == *value {
+ found = true
+ break
+ }
+ }
+
+ if !found {
+ allowed := strings.Join(option.Choices[0:len(option.Choices)-1], ", ")
+
+ if len(option.Choices) > 1 {
+ allowed += " or " + option.Choices[len(option.Choices)-1]
+ }
+
+ return newErrorf(ErrInvalidChoice,
+ "Invalid value `%s' for option `%s'. Allowed values are: %s",
+ *value, option, allowed)
+ }
+ }
+
+ if option.isFunc() {
+ return option.call(value)
+ } else if value != nil {
+ return convert(*value, option.value, option.tag)
+ }
+
+ return convert("", option.value, option.tag)
+}
+
+func (option *Option) canCli() bool {
+ return option.ShortName != 0 || len(option.LongName) != 0
+}
+
+func (option *Option) canArgument() bool {
+ if u := option.isUnmarshaler(); u != nil {
+ return true
+ }
+
+ return !option.isBool()
+}
+
+func (option *Option) emptyValue() reflect.Value {
+ tp := option.value.Type()
+
+ if tp.Kind() == reflect.Map {
+ return reflect.MakeMap(tp)
+ }
+
+ return reflect.Zero(tp)
+}
+
+func (option *Option) empty() {
+ if !option.isFunc() {
+ option.value.Set(option.emptyValue())
+ }
+}
+
+func (option *Option) clearDefault() {
+ usedDefault := option.Default
+
+ if envKey := option.EnvDefaultKey; envKey != "" {
+ if value, ok := os.LookupEnv(envKey); ok {
+ if option.EnvDefaultDelim != "" {
+ usedDefault = strings.Split(value,
+ option.EnvDefaultDelim)
+ } else {
+ usedDefault = []string{value}
+ }
+ }
+ }
+
+ option.isSetDefault = true
+
+ if len(usedDefault) > 0 {
+ option.empty()
+
+ for _, d := range usedDefault {
+ option.set(&d)
+ option.isSetDefault = true
+ }
+ } else {
+ tp := option.value.Type()
+
+ switch tp.Kind() {
+ case reflect.Map:
+ if option.value.IsNil() {
+ option.empty()
+ }
+ case reflect.Slice:
+ if option.value.IsNil() {
+ option.empty()
+ }
+ }
+ }
+}
+
+func (option *Option) valueIsDefault() bool {
+ // Check if the value of the option corresponds to its
+ // default value
+ emptyval := option.emptyValue()
+
+ checkvalptr := reflect.New(emptyval.Type())
+ checkval := reflect.Indirect(checkvalptr)
+
+ checkval.Set(emptyval)
+
+ if len(option.Default) != 0 {
+ for _, v := range option.Default {
+ convert(v, checkval, option.tag)
+ }
+ }
+
+ return reflect.DeepEqual(option.value.Interface(), checkval.Interface())
+}
+
+func (option *Option) isUnmarshaler() Unmarshaler {
+ v := option.value
+
+ for {
+ if !v.CanInterface() {
+ break
+ }
+
+ i := v.Interface()
+
+ if u, ok := i.(Unmarshaler); ok {
+ return u
+ }
+
+ if !v.CanAddr() {
+ break
+ }
+
+ v = v.Addr()
+ }
+
+ return nil
+}
+
+func (option *Option) isBool() bool {
+ tp := option.value.Type()
+
+ for {
+ switch tp.Kind() {
+ case reflect.Slice, reflect.Ptr:
+ tp = tp.Elem()
+ case reflect.Bool:
+ return true
+ case reflect.Func:
+ return tp.NumIn() == 0
+ default:
+ return false
+ }
+ }
+}
+
+func (option *Option) isSignedNumber() bool {
+ tp := option.value.Type()
+
+ for {
+ switch tp.Kind() {
+ case reflect.Slice, reflect.Ptr:
+ tp = tp.Elem()
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Float32, reflect.Float64:
+ return true
+ default:
+ return false
+ }
+ }
+}
+
+func (option *Option) isFunc() bool {
+ return option.value.Type().Kind() == reflect.Func
+}
+
+func (option *Option) call(value *string) error {
+ var retval []reflect.Value
+
+ if value == nil {
+ retval = option.value.Call(nil)
+ } else {
+ tp := option.value.Type().In(0)
+
+ val := reflect.New(tp)
+ val = reflect.Indirect(val)
+
+ if err := convert(*value, val, option.tag); err != nil {
+ return err
+ }
+
+ retval = option.value.Call([]reflect.Value{val})
+ }
+
+ if len(retval) == 1 && retval[0].Type() == reflect.TypeOf((*error)(nil)).Elem() {
+ if retval[0].Interface() == nil {
+ return nil
+ }
+
+ return retval[0].Interface().(error)
+ }
+
+ return nil
+}
+
+func (option *Option) updateDefaultLiteral() {
+ defs := option.Default
+ def := ""
+
+ if len(defs) == 0 && option.canArgument() {
+ var showdef bool
+
+ switch option.field.Type.Kind() {
+ case reflect.Func, reflect.Ptr:
+ showdef = !option.value.IsNil()
+ case reflect.Slice, reflect.String, reflect.Array:
+ showdef = option.value.Len() > 0
+ case reflect.Map:
+ showdef = !option.value.IsNil() && option.value.Len() > 0
+ default:
+ zeroval := reflect.Zero(option.field.Type)
+ showdef = !reflect.DeepEqual(zeroval.Interface(), option.value.Interface())
+ }
+
+ if showdef {
+ def, _ = convertToString(option.value, option.tag)
+ }
+ } else if len(defs) != 0 {
+ l := len(defs) - 1
+
+ for i := 0; i < l; i++ {
+ def += quoteIfNeeded(defs[i]) + ", "
+ }
+
+ def += quoteIfNeeded(defs[l])
+ }
+
+ option.defaultLiteral = def
+}
+
+func (option *Option) shortAndLongName() string {
+ ret := &bytes.Buffer{}
+
+ if option.ShortName != 0 {
+ ret.WriteRune(defaultShortOptDelimiter)
+ ret.WriteRune(option.ShortName)
+ }
+
+ if len(option.LongName) != 0 {
+ if option.ShortName != 0 {
+ ret.WriteRune('/')
+ }
+
+ ret.WriteString(option.LongName)
+ }
+
+ return ret.String()
+}
diff --git a/vendor/github.com/jessevdk/go-flags/optstyle_other.go b/vendor/github.com/jessevdk/go-flags/optstyle_other.go
new file mode 100644
index 0000000..56dfdae
--- /dev/null
+++ b/vendor/github.com/jessevdk/go-flags/optstyle_other.go
@@ -0,0 +1,67 @@
+// +build !windows forceposix
+
+package flags
+
+import (
+ "strings"
+)
+
+const (
+ defaultShortOptDelimiter = '-'
+ defaultLongOptDelimiter = "--"
+ defaultNameArgDelimiter = '='
+)
+
+func argumentStartsOption(arg string) bool {
+ return len(arg) > 0 && arg[0] == '-'
+}
+
+func argumentIsOption(arg string) bool {
+ if len(arg) > 1 && arg[0] == '-' && arg[1] != '-' {
+ return true
+ }
+
+ if len(arg) > 2 && arg[0] == '-' && arg[1] == '-' && arg[2] != '-' {
+ return true
+ }
+
+ return false
+}
+
+// stripOptionPrefix returns the option without the prefix and whether or
+// not the option is a long option or not.
+func stripOptionPrefix(optname string) (prefix string, name string, islong bool) {
+ if strings.HasPrefix(optname, "--") {
+ return "--", optname[2:], true
+ } else if strings.HasPrefix(optname, "-") {
+ return "-", optname[1:], false
+ }
+
+ return "", optname, false
+}
+
+// splitOption attempts to split the passed option into a name and an argument.
+// When there is no argument specified, nil will be returned for it.
+func splitOption(prefix string, option string, islong bool) (string, string, *string) {
+ pos := strings.Index(option, "=")
+
+ if (islong && pos >= 0) || (!islong && pos == 1) {
+ rest := option[pos+1:]
+ return option[:pos], "=", &rest
+ }
+
+ return option, "", nil
+}
+
+// addHelpGroup adds a new group that contains default help parameters.
+func (c *Command) addHelpGroup(showHelp func() error) *Group {
+ var help struct {
+ ShowHelp func() error `short:"h" long:"help" description:"Show this help message"`
+ }
+
+ help.ShowHelp = showHelp
+ ret, _ := c.AddGroup("Help Options", "", &help)
+ ret.isBuiltinHelp = true
+
+ return ret
+}
diff --git a/vendor/github.com/jessevdk/go-flags/optstyle_windows.go b/vendor/github.com/jessevdk/go-flags/optstyle_windows.go
new file mode 100644
index 0000000..f3f28ae
--- /dev/null
+++ b/vendor/github.com/jessevdk/go-flags/optstyle_windows.go
@@ -0,0 +1,108 @@
+// +build !forceposix
+
+package flags
+
+import (
+ "strings"
+)
+
+// Windows uses a front slash for both short and long options. Also it uses
+// a colon for name/argument delimter.
+const (
+ defaultShortOptDelimiter = '/'
+ defaultLongOptDelimiter = "/"
+ defaultNameArgDelimiter = ':'
+)
+
+func argumentStartsOption(arg string) bool {
+ return len(arg) > 0 && (arg[0] == '-' || arg[0] == '/')
+}
+
+func argumentIsOption(arg string) bool {
+ // Windows-style options allow front slash for the option
+ // delimiter.
+ if len(arg) > 1 && arg[0] == '/' {
+ return true
+ }
+
+ if len(arg) > 1 && arg[0] == '-' && arg[1] != '-' {
+ return true
+ }
+
+ if len(arg) > 2 && arg[0] == '-' && arg[1] == '-' && arg[2] != '-' {
+ return true
+ }
+
+ return false
+}
+
+// stripOptionPrefix returns the option without the prefix and whether or
+// not the option is a long option or not.
+func stripOptionPrefix(optname string) (prefix string, name string, islong bool) {
+ // Determine if the argument is a long option or not. Windows
+ // typically supports both long and short options with a single
+ // front slash as the option delimiter, so handle this situation
+ // nicely.
+ possplit := 0
+
+ if strings.HasPrefix(optname, "--") {
+ possplit = 2
+ islong = true
+ } else if strings.HasPrefix(optname, "-") {
+ possplit = 1
+ islong = false
+ } else if strings.HasPrefix(optname, "/") {
+ possplit = 1
+ islong = len(optname) > 2
+ }
+
+ return optname[:possplit], optname[possplit:], islong
+}
+
+// splitOption attempts to split the passed option into a name and an argument.
+// When there is no argument specified, nil will be returned for it.
+func splitOption(prefix string, option string, islong bool) (string, string, *string) {
+ if len(option) == 0 {
+ return option, "", nil
+ }
+
+ // Windows typically uses a colon for the option name and argument
+ // delimiter while POSIX typically uses an equals. Support both styles,
+ // but don't allow the two to be mixed. That is to say /foo:bar and
+ // --foo=bar are acceptable, but /foo=bar and --foo:bar are not.
+ var pos int
+ var sp string
+
+ if prefix == "/" {
+ sp = ":"
+ pos = strings.Index(option, sp)
+ } else if len(prefix) > 0 {
+ sp = "="
+ pos = strings.Index(option, sp)
+ }
+
+ if (islong && pos >= 0) || (!islong && pos == 1) {
+ rest := option[pos+1:]
+ return option[:pos], sp, &rest
+ }
+
+ return option, "", nil
+}
+
+// addHelpGroup adds a new group that contains default help parameters.
+func (c *Command) addHelpGroup(showHelp func() error) *Group {
+ // Windows CLI applications typically use /? for help, so make both
+ // that available as well as the POSIX style h and help.
+ var help struct {
+ ShowHelpWindows func() error `short:"?" description:"Show this help message"`
+ ShowHelpPosix func() error `short:"h" long:"help" description:"Show this help message"`
+ }
+
+ help.ShowHelpWindows = showHelp
+ help.ShowHelpPosix = showHelp
+
+ ret, _ := c.AddGroup("Help Options", "", &help)
+ ret.isBuiltinHelp = true
+
+ return ret
+}
diff --git a/vendor/github.com/jessevdk/go-flags/parser.go b/vendor/github.com/jessevdk/go-flags/parser.go
new file mode 100644
index 0000000..0a7922a
--- /dev/null
+++ b/vendor/github.com/jessevdk/go-flags/parser.go
@@ -0,0 +1,700 @@
+// Copyright 2012 Jesse van den Kieboom. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package flags
+
+import (
+ "bytes"
+ "fmt"
+ "os"
+ "path"
+ "sort"
+ "strings"
+ "unicode/utf8"
+)
+
+// A Parser provides command line option parsing. It can contain several
+// option groups each with their own set of options.
+type Parser struct {
+ // Embedded, see Command for more information
+ *Command
+
+ // A usage string to be displayed in the help message.
+ Usage string
+
+ // Option flags changing the behavior of the parser.
+ Options Options
+
+ // NamespaceDelimiter separates group namespaces and option long names
+ NamespaceDelimiter string
+
+ // UnknownOptionsHandler is a function which gets called when the parser
+ // encounters an unknown option. The function receives the unknown option
+ // name, a SplitArgument which specifies its value if set with an argument
+ // separator, and the remaining command line arguments.
+ // It should return a new list of remaining arguments to continue parsing,
+ // or an error to indicate a parse failure.
+ UnknownOptionHandler func(option string, arg SplitArgument, args []string) ([]string, error)
+
+ // CompletionHandler is a function gets called to handle the completion of
+ // items. By default, the items are printed and the application is exited.
+ // You can override this default behavior by specifying a custom CompletionHandler.
+ CompletionHandler func(items []Completion)
+
+ // CommandHandler is a function that gets called to handle execution of a
+ // command. By default, the command will simply be executed. This can be
+ // overridden to perform certain actions (such as applying global flags)
+ // just before the command is executed. Note that if you override the
+ // handler it is your responsibility to call the command.Execute function.
+ //
+ // The command passed into CommandHandler may be nil in case there is no
+ // command to be executed when parsing has finished.
+ CommandHandler func(command Commander, args []string) error
+
+ internalError error
+}
+
+// SplitArgument represents the argument value of an option that was passed using
+// an argument separator.
+type SplitArgument interface {
+ // String returns the option's value as a string, and a boolean indicating
+ // if the option was present.
+ Value() (string, bool)
+}
+
+type strArgument struct {
+ value *string
+}
+
+func (s strArgument) Value() (string, bool) {
+ if s.value == nil {
+ return "", false
+ }
+
+ return *s.value, true
+}
+
+// Options provides parser options that change the behavior of the option
+// parser.
+type Options uint
+
+const (
+ // None indicates no options.
+ None Options = 0
+
+ // HelpFlag adds a default Help Options group to the parser containing
+ // -h and --help options. When either -h or --help is specified on the
+ // command line, the parser will return the special error of type
+ // ErrHelp. When PrintErrors is also specified, then the help message
+ // will also be automatically printed to os.Stdout.
+ HelpFlag = 1 << iota
+
+ // PassDoubleDash passes all arguments after a double dash, --, as
+ // remaining command line arguments (i.e. they will not be parsed for
+ // flags).
+ PassDoubleDash
+
+ // IgnoreUnknown ignores any unknown options and passes them as
+ // remaining command line arguments instead of generating an error.
+ IgnoreUnknown
+
+ // PrintErrors prints any errors which occurred during parsing to
+ // os.Stderr. In the special case of ErrHelp, the message will be printed
+ // to os.Stdout.
+ PrintErrors
+
+ // PassAfterNonOption passes all arguments after the first non option
+ // as remaining command line arguments. This is equivalent to strict
+ // POSIX processing.
+ PassAfterNonOption
+
+ // Default is a convenient default set of options which should cover
+ // most of the uses of the flags package.
+ Default = HelpFlag | PrintErrors | PassDoubleDash
+)
+
+type parseState struct {
+ arg string
+ args []string
+ retargs []string
+ positional []*Arg
+ err error
+
+ command *Command
+ lookup lookup
+}
+
+// Parse is a convenience function to parse command line options with default
+// settings. The provided data is a pointer to a struct representing the
+// default option group (named "Application Options"). For more control, use
+// flags.NewParser.
+func Parse(data interface{}) ([]string, error) {
+ return NewParser(data, Default).Parse()
+}
+
+// ParseArgs is a convenience function to parse command line options with default
+// settings. The provided data is a pointer to a struct representing the
+// default option group (named "Application Options"). The args argument is
+// the list of command line arguments to parse. If you just want to parse the
+// default program command line arguments (i.e. os.Args), then use flags.Parse
+// instead. For more control, use flags.NewParser.
+func ParseArgs(data interface{}, args []string) ([]string, error) {
+ return NewParser(data, Default).ParseArgs(args)
+}
+
+// NewParser creates a new parser. It uses os.Args[0] as the application
+// name and then calls Parser.NewNamedParser (see Parser.NewNamedParser for
+// more details). The provided data is a pointer to a struct representing the
+// default option group (named "Application Options"), or nil if the default
+// group should not be added. The options parameter specifies a set of options
+// for the parser.
+func NewParser(data interface{}, options Options) *Parser {
+ p := NewNamedParser(path.Base(os.Args[0]), options)
+
+ if data != nil {
+ g, err := p.AddGroup("Application Options", "", data)
+
+ if err == nil {
+ g.parent = p
+ }
+
+ p.internalError = err
+ }
+
+ return p
+}
+
+// NewNamedParser creates a new parser. The appname is used to display the
+// executable name in the built-in help message. Option groups and commands can
+// be added to this parser by using AddGroup and AddCommand.
+func NewNamedParser(appname string, options Options) *Parser {
+ p := &Parser{
+ Command: newCommand(appname, "", "", nil),
+ Options: options,
+ NamespaceDelimiter: ".",
+ }
+
+ p.Command.parent = p
+
+ return p
+}
+
+// Parse parses the command line arguments from os.Args using Parser.ParseArgs.
+// For more detailed information see ParseArgs.
+func (p *Parser) Parse() ([]string, error) {
+ return p.ParseArgs(os.Args[1:])
+}
+
+// ParseArgs parses the command line arguments according to the option groups that
+// were added to the parser. On successful parsing of the arguments, the
+// remaining, non-option, arguments (if any) are returned. The returned error
+// indicates a parsing error and can be used with PrintError to display
+// contextual information on where the error occurred exactly.
+//
+// When the common help group has been added (AddHelp) and either -h or --help
+// was specified in the command line arguments, a help message will be
+// automatically printed if the PrintErrors option is enabled.
+// Furthermore, the special error type ErrHelp is returned.
+// It is up to the caller to exit the program if so desired.
+func (p *Parser) ParseArgs(args []string) ([]string, error) {
+ if p.internalError != nil {
+ return nil, p.internalError
+ }
+
+ p.eachOption(func(c *Command, g *Group, option *Option) {
+ option.isSet = false
+ option.isSetDefault = false
+ option.updateDefaultLiteral()
+ })
+
+ // Add built-in help group to all commands if necessary
+ if (p.Options & HelpFlag) != None {
+ p.addHelpGroups(p.showBuiltinHelp)
+ }
+
+ compval := os.Getenv("GO_FLAGS_COMPLETION")
+
+ if len(compval) != 0 {
+ comp := &completion{parser: p}
+ items := comp.complete(args)
+
+ if p.CompletionHandler != nil {
+ p.CompletionHandler(items)
+ } else {
+ comp.print(items, compval == "verbose")
+ os.Exit(0)
+ }
+
+ return nil, nil
+ }
+
+ s := &parseState{
+ args: args,
+ retargs: make([]string, 0, len(args)),
+ }
+
+ p.fillParseState(s)
+
+ for !s.eof() {
+ arg := s.pop()
+
+ // When PassDoubleDash is set and we encounter a --, then
+ // simply append all the rest as arguments and break out
+ if (p.Options&PassDoubleDash) != None && arg == "--" {
+ s.addArgs(s.args...)
+ break
+ }
+
+ if !argumentIsOption(arg) {
+ // Note: this also sets s.err, so we can just check for
+ // nil here and use s.err later
+ if p.parseNonOption(s) != nil {
+ break
+ }
+
+ continue
+ }
+
+ var err error
+
+ prefix, optname, islong := stripOptionPrefix(arg)
+ optname, _, argument := splitOption(prefix, optname, islong)
+
+ if islong {
+ err = p.parseLong(s, optname, argument)
+ } else {
+ err = p.parseShort(s, optname, argument)
+ }
+
+ if err != nil {
+ ignoreUnknown := (p.Options & IgnoreUnknown) != None
+ parseErr := wrapError(err)
+
+ if parseErr.Type != ErrUnknownFlag || (!ignoreUnknown && p.UnknownOptionHandler == nil) {
+ s.err = parseErr
+ break
+ }
+
+ if ignoreUnknown {
+ s.addArgs(arg)
+ } else if p.UnknownOptionHandler != nil {
+ modifiedArgs, err := p.UnknownOptionHandler(optname, strArgument{argument}, s.args)
+
+ if err != nil {
+ s.err = err
+ break
+ }
+
+ s.args = modifiedArgs
+ }
+ }
+ }
+
+ if s.err == nil {
+ p.eachOption(func(c *Command, g *Group, option *Option) {
+ if option.preventDefault {
+ return
+ }
+
+ option.clearDefault()
+ })
+
+ s.checkRequired(p)
+ }
+
+ var reterr error
+
+ if s.err != nil {
+ reterr = s.err
+ } else if len(s.command.commands) != 0 && !s.command.SubcommandsOptional {
+ reterr = s.estimateCommand()
+ } else if cmd, ok := s.command.data.(Commander); ok {
+ if p.CommandHandler != nil {
+ reterr = p.CommandHandler(cmd, s.retargs)
+ } else {
+ reterr = cmd.Execute(s.retargs)
+ }
+ } else if p.CommandHandler != nil {
+ reterr = p.CommandHandler(nil, s.retargs)
+ }
+
+ if reterr != nil {
+ var retargs []string
+
+ if ourErr, ok := reterr.(*Error); !ok || ourErr.Type != ErrHelp {
+ retargs = append([]string{s.arg}, s.args...)
+ } else {
+ retargs = s.args
+ }
+
+ return retargs, p.printError(reterr)
+ }
+
+ return s.retargs, nil
+}
+
+func (p *parseState) eof() bool {
+ return len(p.args) == 0
+}
+
+func (p *parseState) pop() string {
+ if p.eof() {
+ return ""
+ }
+
+ p.arg = p.args[0]
+ p.args = p.args[1:]
+
+ return p.arg
+}
+
+func (p *parseState) peek() string {
+ if p.eof() {
+ return ""
+ }
+
+ return p.args[0]
+}
+
+func (p *parseState) checkRequired(parser *Parser) error {
+ c := parser.Command
+
+ var required []*Option
+
+ for c != nil {
+ c.eachGroup(func(g *Group) {
+ for _, option := range g.options {
+ if !option.isSet && option.Required {
+ required = append(required, option)
+ }
+ }
+ })
+
+ c = c.Active
+ }
+
+ if len(required) == 0 {
+ if len(p.positional) > 0 {
+ var reqnames []string
+
+ for _, arg := range p.positional {
+ argRequired := (!arg.isRemaining() && p.command.ArgsRequired) || arg.Required != -1 || arg.RequiredMaximum != -1
+
+ if !argRequired {
+ continue
+ }
+
+ if arg.isRemaining() {
+ if arg.value.Len() < arg.Required {
+ var arguments string
+
+ if arg.Required > 1 {
+ arguments = "arguments, but got only " + fmt.Sprintf("%d", arg.value.Len())
+ } else {
+ arguments = "argument"
+ }
+
+ reqnames = append(reqnames, "`"+arg.Name+" (at least "+fmt.Sprintf("%d", arg.Required)+" "+arguments+")`")
+ } else if arg.RequiredMaximum != -1 && arg.value.Len() > arg.RequiredMaximum {
+ if arg.RequiredMaximum == 0 {
+ reqnames = append(reqnames, "`"+arg.Name+" (zero arguments)`")
+ } else {
+ var arguments string
+
+ if arg.RequiredMaximum > 1 {
+ arguments = "arguments, but got " + fmt.Sprintf("%d", arg.value.Len())
+ } else {
+ arguments = "argument"
+ }
+
+ reqnames = append(reqnames, "`"+arg.Name+" (at most "+fmt.Sprintf("%d", arg.RequiredMaximum)+" "+arguments+")`")
+ }
+ }
+ } else {
+ reqnames = append(reqnames, "`"+arg.Name+"`")
+ }
+ }
+
+ if len(reqnames) == 0 {
+ return nil
+ }
+
+ var msg string
+
+ if len(reqnames) == 1 {
+ msg = fmt.Sprintf("the required argument %s was not provided", reqnames[0])
+ } else {
+ msg = fmt.Sprintf("the required arguments %s and %s were not provided",
+ strings.Join(reqnames[:len(reqnames)-1], ", "), reqnames[len(reqnames)-1])
+ }
+
+ p.err = newError(ErrRequired, msg)
+ return p.err
+ }
+
+ return nil
+ }
+
+ names := make([]string, 0, len(required))
+
+ for _, k := range required {
+ names = append(names, "`"+k.String()+"'")
+ }
+
+ sort.Strings(names)
+
+ var msg string
+
+ if len(names) == 1 {
+ msg = fmt.Sprintf("the required flag %s was not specified", names[0])
+ } else {
+ msg = fmt.Sprintf("the required flags %s and %s were not specified",
+ strings.Join(names[:len(names)-1], ", "), names[len(names)-1])
+ }
+
+ p.err = newError(ErrRequired, msg)
+ return p.err
+}
+
+func (p *parseState) estimateCommand() error {
+ commands := p.command.sortedVisibleCommands()
+ cmdnames := make([]string, len(commands))
+
+ for i, v := range commands {
+ cmdnames[i] = v.Name
+ }
+
+ var msg string
+ var errtype ErrorType
+
+ if len(p.retargs) != 0 {
+ c, l := closestChoice(p.retargs[0], cmdnames)
+ msg = fmt.Sprintf("Unknown command `%s'", p.retargs[0])
+ errtype = ErrUnknownCommand
+
+ if float32(l)/float32(len(c)) < 0.5 {
+ msg = fmt.Sprintf("%s, did you mean `%s'?", msg, c)
+ } else if len(cmdnames) == 1 {
+ msg = fmt.Sprintf("%s. You should use the %s command",
+ msg,
+ cmdnames[0])
+ } else if len(cmdnames) > 1 {
+ msg = fmt.Sprintf("%s. Please specify one command of: %s or %s",
+ msg,
+ strings.Join(cmdnames[:len(cmdnames)-1], ", "),
+ cmdnames[len(cmdnames)-1])
+ }
+ } else {
+ errtype = ErrCommandRequired
+
+ if len(cmdnames) == 1 {
+ msg = fmt.Sprintf("Please specify the %s command", cmdnames[0])
+ } else if len(cmdnames) > 1 {
+ msg = fmt.Sprintf("Please specify one command of: %s or %s",
+ strings.Join(cmdnames[:len(cmdnames)-1], ", "),
+ cmdnames[len(cmdnames)-1])
+ }
+ }
+
+ return newError(errtype, msg)
+}
+
+func (p *Parser) parseOption(s *parseState, name string, option *Option, canarg bool, argument *string) (err error) {
+ if !option.canArgument() {
+ if argument != nil {
+ return newErrorf(ErrNoArgumentForBool, "bool flag `%s' cannot have an argument", option)
+ }
+
+ err = option.set(nil)
+ } else if argument != nil || (canarg && !s.eof()) {
+ var arg string
+
+ if argument != nil {
+ arg = *argument
+ } else {
+ arg = s.pop()
+
+ if argumentIsOption(arg) && !(option.isSignedNumber() && len(arg) > 1 && arg[0] == '-' && arg[1] >= '0' && arg[1] <= '9') {
+ return newErrorf(ErrExpectedArgument, "expected argument for flag `%s', but got option `%s'", option, arg)
+ } else if p.Options&PassDoubleDash != 0 && arg == "--" {
+ return newErrorf(ErrExpectedArgument, "expected argument for flag `%s', but got double dash `--'", option)
+ }
+ }
+
+ if option.tag.Get("unquote") != "false" {
+ arg, err = unquoteIfPossible(arg)
+ }
+
+ if err == nil {
+ err = option.set(&arg)
+ }
+ } else if option.OptionalArgument {
+ option.empty()
+
+ for _, v := range option.OptionalValue {
+ err = option.set(&v)
+
+ if err != nil {
+ break
+ }
+ }
+ } else {
+ err = newErrorf(ErrExpectedArgument, "expected argument for flag `%s'", option)
+ }
+
+ if err != nil {
+ if _, ok := err.(*Error); !ok {
+ err = newErrorf(ErrMarshal, "invalid argument for flag `%s' (expected %s): %s",
+ option,
+ option.value.Type(),
+ err.Error())
+ }
+ }
+
+ return err
+}
+
+func (p *Parser) parseLong(s *parseState, name string, argument *string) error {
+ if option := s.lookup.longNames[name]; option != nil {
+ // Only long options that are required can consume an argument
+ // from the argument list
+ canarg := !option.OptionalArgument
+
+ return p.parseOption(s, name, option, canarg, argument)
+ }
+
+ return newErrorf(ErrUnknownFlag, "unknown flag `%s'", name)
+}
+
+func (p *Parser) splitShortConcatArg(s *parseState, optname string) (string, *string) {
+ c, n := utf8.DecodeRuneInString(optname)
+
+ if n == len(optname) {
+ return optname, nil
+ }
+
+ first := string(c)
+
+ if option := s.lookup.shortNames[first]; option != nil && option.canArgument() {
+ arg := optname[n:]
+ return first, &arg
+ }
+
+ return optname, nil
+}
+
+func (p *Parser) parseShort(s *parseState, optname string, argument *string) error {
+ if argument == nil {
+ optname, argument = p.splitShortConcatArg(s, optname)
+ }
+
+ for i, c := range optname {
+ shortname := string(c)
+
+ if option := s.lookup.shortNames[shortname]; option != nil {
+ // Only the last short argument can consume an argument from
+ // the arguments list, and only if it's non optional
+ canarg := (i+utf8.RuneLen(c) == len(optname)) && !option.OptionalArgument
+
+ if err := p.parseOption(s, shortname, option, canarg, argument); err != nil {
+ return err
+ }
+ } else {
+ return newErrorf(ErrUnknownFlag, "unknown flag `%s'", shortname)
+ }
+
+ // Only the first option can have a concatted argument, so just
+ // clear argument here
+ argument = nil
+ }
+
+ return nil
+}
+
+func (p *parseState) addArgs(args ...string) error {
+ for len(p.positional) > 0 && len(args) > 0 {
+ arg := p.positional[0]
+
+ if err := convert(args[0], arg.value, arg.tag); err != nil {
+ p.err = err
+ return err
+ }
+
+ if !arg.isRemaining() {
+ p.positional = p.positional[1:]
+ }
+
+ args = args[1:]
+ }
+
+ p.retargs = append(p.retargs, args...)
+ return nil
+}
+
+func (p *Parser) parseNonOption(s *parseState) error {
+ if len(s.positional) > 0 {
+ return s.addArgs(s.arg)
+ }
+
+ if len(s.command.commands) > 0 && len(s.retargs) == 0 {
+ if cmd := s.lookup.commands[s.arg]; cmd != nil {
+ s.command.Active = cmd
+ cmd.fillParseState(s)
+
+ return nil
+ } else if !s.command.SubcommandsOptional {
+ s.addArgs(s.arg)
+ return newErrorf(ErrUnknownCommand, "Unknown command `%s'", s.arg)
+ }
+ }
+
+ if (p.Options & PassAfterNonOption) != None {
+ // If PassAfterNonOption is set then all remaining arguments
+ // are considered positional
+ if err := s.addArgs(s.arg); err != nil {
+ return err
+ }
+
+ if err := s.addArgs(s.args...); err != nil {
+ return err
+ }
+
+ s.args = []string{}
+ } else {
+ return s.addArgs(s.arg)
+ }
+
+ return nil
+}
+
+func (p *Parser) showBuiltinHelp() error {
+ var b bytes.Buffer
+
+ p.WriteHelp(&b)
+ return newError(ErrHelp, b.String())
+}
+
+func (p *Parser) printError(err error) error {
+ if err != nil && (p.Options&PrintErrors) != None {
+ flagsErr, ok := err.(*Error)
+
+ if ok && flagsErr.Type == ErrHelp {
+ fmt.Fprintln(os.Stdout, err)
+ } else {
+ fmt.Fprintln(os.Stderr, err)
+ }
+ }
+
+ return err
+}
+
+func (p *Parser) clearIsSet() {
+ p.eachCommand(func(c *Command) {
+ c.eachGroup(func(g *Group) {
+ for _, option := range g.options {
+ option.isSet = false
+ }
+ })
+ }, true)
+}
diff --git a/vendor/github.com/jessevdk/go-flags/termsize.go b/vendor/github.com/jessevdk/go-flags/termsize.go
new file mode 100644
index 0000000..1ca6a85
--- /dev/null
+++ b/vendor/github.com/jessevdk/go-flags/termsize.go
@@ -0,0 +1,28 @@
+// +build !windows,!plan9,!solaris,!appengine
+
+package flags
+
+import (
+ "syscall"
+ "unsafe"
+)
+
+type winsize struct {
+ row, col uint16
+ xpixel, ypixel uint16
+}
+
+func getTerminalColumns() int {
+ ws := winsize{}
+
+ if tIOCGWINSZ != 0 {
+ syscall.Syscall(syscall.SYS_IOCTL,
+ uintptr(0),
+ uintptr(tIOCGWINSZ),
+ uintptr(unsafe.Pointer(&ws)))
+
+ return int(ws.col)
+ }
+
+ return 80
+}
diff --git a/vendor/github.com/jessevdk/go-flags/termsize_nosysioctl.go b/vendor/github.com/jessevdk/go-flags/termsize_nosysioctl.go
new file mode 100644
index 0000000..3d5385b
--- /dev/null
+++ b/vendor/github.com/jessevdk/go-flags/termsize_nosysioctl.go
@@ -0,0 +1,7 @@
+// +build windows plan9 solaris appengine
+
+package flags
+
+func getTerminalColumns() int {
+ return 80
+}
diff --git a/vendor/github.com/jessevdk/go-flags/tiocgwinsz_bsdish.go b/vendor/github.com/jessevdk/go-flags/tiocgwinsz_bsdish.go
new file mode 100644
index 0000000..fcc1186
--- /dev/null
+++ b/vendor/github.com/jessevdk/go-flags/tiocgwinsz_bsdish.go
@@ -0,0 +1,7 @@
+// +build darwin freebsd netbsd openbsd
+
+package flags
+
+const (
+ tIOCGWINSZ = 0x40087468
+)
diff --git a/vendor/github.com/jessevdk/go-flags/tiocgwinsz_linux.go b/vendor/github.com/jessevdk/go-flags/tiocgwinsz_linux.go
new file mode 100644
index 0000000..e3975e2
--- /dev/null
+++ b/vendor/github.com/jessevdk/go-flags/tiocgwinsz_linux.go
@@ -0,0 +1,7 @@
+// +build linux
+
+package flags
+
+const (
+ tIOCGWINSZ = 0x5413
+)
diff --git a/vendor/github.com/jessevdk/go-flags/tiocgwinsz_other.go b/vendor/github.com/jessevdk/go-flags/tiocgwinsz_other.go
new file mode 100644
index 0000000..3082151
--- /dev/null
+++ b/vendor/github.com/jessevdk/go-flags/tiocgwinsz_other.go
@@ -0,0 +1,7 @@
+// +build !darwin,!freebsd,!netbsd,!openbsd,!linux
+
+package flags
+
+const (
+ tIOCGWINSZ = 0
+)
diff --git a/vendor/golang.org/x/sys/unix/mkasm_darwin.go b/vendor/golang.org/x/sys/unix/mkasm_darwin.go
deleted file mode 100644
index 4548b99..0000000
--- a/vendor/golang.org/x/sys/unix/mkasm_darwin.go
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-// mkasm_darwin.go generates assembly trampolines to call libSystem routines from Go.
-//This program must be run after mksyscall.go.
-package main
-
-import (
- "bytes"
- "fmt"
- "io/ioutil"
- "log"
- "os"
- "strings"
-)
-
-func main() {
- in1, err := ioutil.ReadFile("syscall_darwin.go")
- if err != nil {
- log.Fatalf("can't open syscall_darwin.go: %s", err)
- }
- arch := os.Args[1]
- in2, err := ioutil.ReadFile(fmt.Sprintf("syscall_darwin_%s.go", arch))
- if err != nil {
- log.Fatalf("can't open syscall_darwin_%s.go: %s", arch, err)
- }
- in3, err := ioutil.ReadFile(fmt.Sprintf("zsyscall_darwin_%s.go", arch))
- if err != nil {
- log.Fatalf("can't open zsyscall_darwin_%s.go: %s", arch, err)
- }
- in := string(in1) + string(in2) + string(in3)
-
- trampolines := map[string]bool{}
-
- var out bytes.Buffer
-
- fmt.Fprintf(&out, "// go run mkasm_darwin.go %s\n", strings.Join(os.Args[1:], " "))
- fmt.Fprintf(&out, "// Code generated by the command above; DO NOT EDIT.\n")
- fmt.Fprintf(&out, "\n")
- fmt.Fprintf(&out, "// +build go1.12\n")
- fmt.Fprintf(&out, "\n")
- fmt.Fprintf(&out, "#include \"textflag.h\"\n")
- for _, line := range strings.Split(in, "\n") {
- if !strings.HasPrefix(line, "func ") || !strings.HasSuffix(line, "_trampoline()") {
- continue
- }
- fn := line[5 : len(line)-13]
- if !trampolines[fn] {
- trampolines[fn] = true
- fmt.Fprintf(&out, "TEXT ·%s_trampoline(SB),NOSPLIT,$0-0\n", fn)
- fmt.Fprintf(&out, "\tJMP\t%s(SB)\n", fn)
- }
- }
- err = ioutil.WriteFile(fmt.Sprintf("zsyscall_darwin_%s.s", arch), out.Bytes(), 0644)
- if err != nil {
- log.Fatalf("can't write zsyscall_darwin_%s.s: %s", arch, err)
- }
-}
diff --git a/vendor/golang.org/x/sys/unix/mkpost.go b/vendor/golang.org/x/sys/unix/mkpost.go
deleted file mode 100644
index 9feddd0..0000000
--- a/vendor/golang.org/x/sys/unix/mkpost.go
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-// mkpost processes the output of cgo -godefs to
-// modify the generated types. It is used to clean up
-// the sys API in an architecture specific manner.
-//
-// mkpost is run after cgo -godefs; see README.md.
-package main
-
-import (
- "bytes"
- "fmt"
- "go/format"
- "io/ioutil"
- "log"
- "os"
- "regexp"
-)
-
-func main() {
- // Get the OS and architecture (using GOARCH_TARGET if it exists)
- goos := os.Getenv("GOOS")
- goarch := os.Getenv("GOARCH_TARGET")
- if goarch == "" {
- goarch = os.Getenv("GOARCH")
- }
- // Check that we are using the Docker-based build system if we should be.
- if goos == "linux" {
- if os.Getenv("GOLANG_SYS_BUILD") != "docker" {
- os.Stderr.WriteString("In the Docker-based build system, mkpost should not be called directly.\n")
- os.Stderr.WriteString("See README.md\n")
- os.Exit(1)
- }
- }
-
- b, err := ioutil.ReadAll(os.Stdin)
- if err != nil {
- log.Fatal(err)
- }
-
- // Intentionally export __val fields in Fsid and Sigset_t
- valRegex := regexp.MustCompile(`type (Fsid|Sigset_t) struct {(\s+)X__val(\s+\S+\s+)}`)
- b = valRegex.ReplaceAll(b, []byte("type $1 struct {${2}Val$3}"))
-
- // Intentionally export __fds_bits field in FdSet
- fdSetRegex := regexp.MustCompile(`type (FdSet) struct {(\s+)X__fds_bits(\s+\S+\s+)}`)
- b = fdSetRegex.ReplaceAll(b, []byte("type $1 struct {${2}Bits$3}"))
-
- // If we have empty Ptrace structs, we should delete them. Only s390x emits
- // nonempty Ptrace structs.
- ptraceRexexp := regexp.MustCompile(`type Ptrace((Psw|Fpregs|Per) struct {\s*})`)
- b = ptraceRexexp.ReplaceAll(b, nil)
-
- // Replace the control_regs union with a blank identifier for now.
- controlRegsRegex := regexp.MustCompile(`(Control_regs)\s+\[0\]uint64`)
- b = controlRegsRegex.ReplaceAll(b, []byte("_ [0]uint64"))
-
- // Remove fields that are added by glibc
- // Note that this is unstable as the identifers are private.
- removeFieldsRegex := regexp.MustCompile(`X__glibc\S*`)
- b = removeFieldsRegex.ReplaceAll(b, []byte("_"))
-
- // Convert [65]int8 to [65]byte in Utsname members to simplify
- // conversion to string; see golang.org/issue/20753
- convertUtsnameRegex := regexp.MustCompile(`((Sys|Node|Domain)name|Release|Version|Machine)(\s+)\[(\d+)\]u?int8`)
- b = convertUtsnameRegex.ReplaceAll(b, []byte("$1$3[$4]byte"))
-
- // Convert [1024]int8 to [1024]byte in Ptmget members
- convertPtmget := regexp.MustCompile(`([SC]n)(\s+)\[(\d+)\]u?int8`)
- b = convertPtmget.ReplaceAll(b, []byte("$1[$3]byte"))
-
- // Remove spare fields (e.g. in Statx_t)
- spareFieldsRegex := regexp.MustCompile(`X__spare\S*`)
- b = spareFieldsRegex.ReplaceAll(b, []byte("_"))
-
- // Remove cgo padding fields
- removePaddingFieldsRegex := regexp.MustCompile(`Pad_cgo_\d+`)
- b = removePaddingFieldsRegex.ReplaceAll(b, []byte("_"))
-
- // Remove padding, hidden, or unused fields
- removeFieldsRegex = regexp.MustCompile(`\b(X_\S+|Padding)`)
- b = removeFieldsRegex.ReplaceAll(b, []byte("_"))
-
- // Remove the first line of warning from cgo
- b = b[bytes.IndexByte(b, '\n')+1:]
- // Modify the command in the header to include:
- // mkpost, our own warning, and a build tag.
- replacement := fmt.Sprintf(`$1 | go run mkpost.go
-// Code generated by the command above; see README.md. DO NOT EDIT.
-
-// +build %s,%s`, goarch, goos)
- cgoCommandRegex := regexp.MustCompile(`(cgo -godefs .*)`)
- b = cgoCommandRegex.ReplaceAll(b, []byte(replacement))
-
- // gofmt
- b, err = format.Source(b)
- if err != nil {
- log.Fatal(err)
- }
-
- os.Stdout.Write(b)
-}
diff --git a/vendor/golang.org/x/sys/unix/mksyscall.go b/vendor/golang.org/x/sys/unix/mksyscall.go
deleted file mode 100644
index e4af942..0000000
--- a/vendor/golang.org/x/sys/unix/mksyscall.go
+++ /dev/null
@@ -1,407 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-/*
-This program reads a file containing function prototypes
-(like syscall_darwin.go) and generates system call bodies.
-The prototypes are marked by lines beginning with "//sys"
-and read like func declarations if //sys is replaced by func, but:
- * The parameter lists must give a name for each argument.
- This includes return parameters.
- * The parameter lists must give a type for each argument:
- the (x, y, z int) shorthand is not allowed.
- * If the return parameter is an error number, it must be named errno.
-
-A line beginning with //sysnb is like //sys, except that the
-goroutine will not be suspended during the execution of the system
-call. This must only be used for system calls which can never
-block, as otherwise the system call could cause all goroutines to
-hang.
-*/
-package main
-
-import (
- "bufio"
- "flag"
- "fmt"
- "os"
- "regexp"
- "strings"
-)
-
-var (
- b32 = flag.Bool("b32", false, "32bit big-endian")
- l32 = flag.Bool("l32", false, "32bit little-endian")
- plan9 = flag.Bool("plan9", false, "plan9")
- openbsd = flag.Bool("openbsd", false, "openbsd")
- netbsd = flag.Bool("netbsd", false, "netbsd")
- dragonfly = flag.Bool("dragonfly", false, "dragonfly")
- arm = flag.Bool("arm", false, "arm") // 64-bit value should use (even, odd)-pair
- tags = flag.String("tags", "", "build tags")
- filename = flag.String("output", "", "output file name (standard output if omitted)")
-)
-
-// cmdLine returns this programs's commandline arguments
-func cmdLine() string {
- return "go run mksyscall.go " + strings.Join(os.Args[1:], " ")
-}
-
-// buildTags returns build tags
-func buildTags() string {
- return *tags
-}
-
-// Param is function parameter
-type Param struct {
- Name string
- Type string
-}
-
-// usage prints the program usage
-func usage() {
- fmt.Fprintf(os.Stderr, "usage: go run mksyscall.go [-b32 | -l32] [-tags x,y] [file ...]\n")
- os.Exit(1)
-}
-
-// parseParamList parses parameter list and returns a slice of parameters
-func parseParamList(list string) []string {
- list = strings.TrimSpace(list)
- if list == "" {
- return []string{}
- }
- return regexp.MustCompile(`\s*,\s*`).Split(list, -1)
-}
-
-// parseParam splits a parameter into name and type
-func parseParam(p string) Param {
- ps := regexp.MustCompile(`^(\S*) (\S*)$`).FindStringSubmatch(p)
- if ps == nil {
- fmt.Fprintf(os.Stderr, "malformed parameter: %s\n", p)
- os.Exit(1)
- }
- return Param{ps[1], ps[2]}
-}
-
-func main() {
- // Get the OS and architecture (using GOARCH_TARGET if it exists)
- goos := os.Getenv("GOOS")
- if goos == "" {
- fmt.Fprintln(os.Stderr, "GOOS not defined in environment")
- os.Exit(1)
- }
- goarch := os.Getenv("GOARCH_TARGET")
- if goarch == "" {
- goarch = os.Getenv("GOARCH")
- }
-
- // Check that we are using the Docker-based build system if we should
- if goos == "linux" {
- if os.Getenv("GOLANG_SYS_BUILD") != "docker" {
- fmt.Fprintf(os.Stderr, "In the Docker-based build system, mksyscall should not be called directly.\n")
- fmt.Fprintf(os.Stderr, "See README.md\n")
- os.Exit(1)
- }
- }
-
- flag.Usage = usage
- flag.Parse()
- if len(flag.Args()) <= 0 {
- fmt.Fprintf(os.Stderr, "no files to parse provided\n")
- usage()
- }
-
- endianness := ""
- if *b32 {
- endianness = "big-endian"
- } else if *l32 {
- endianness = "little-endian"
- }
-
- libc := false
- if goos == "darwin" && strings.Contains(buildTags(), ",go1.12") {
- libc = true
- }
- trampolines := map[string]bool{}
-
- text := ""
- for _, path := range flag.Args() {
- file, err := os.Open(path)
- if err != nil {
- fmt.Fprintf(os.Stderr, err.Error())
- os.Exit(1)
- }
- s := bufio.NewScanner(file)
- for s.Scan() {
- t := s.Text()
- t = strings.TrimSpace(t)
- t = regexp.MustCompile(`\s+`).ReplaceAllString(t, ` `)
- nonblock := regexp.MustCompile(`^\/\/sysnb `).FindStringSubmatch(t)
- if regexp.MustCompile(`^\/\/sys `).FindStringSubmatch(t) == nil && nonblock == nil {
- continue
- }
-
- // Line must be of the form
- // func Open(path string, mode int, perm int) (fd int, errno error)
- // Split into name, in params, out params.
- f := regexp.MustCompile(`^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*((?i)SYS_[A-Z0-9_]+))?$`).FindStringSubmatch(t)
- if f == nil {
- fmt.Fprintf(os.Stderr, "%s:%s\nmalformed //sys declaration\n", path, t)
- os.Exit(1)
- }
- funct, inps, outps, sysname := f[2], f[3], f[4], f[5]
-
- // ClockGettime doesn't have a syscall number on Darwin, only generate libc wrappers.
- if goos == "darwin" && !libc && funct == "ClockGettime" {
- continue
- }
-
- // Split argument lists on comma.
- in := parseParamList(inps)
- out := parseParamList(outps)
-
- // Try in vain to keep people from editing this file.
- // The theory is that they jump into the middle of the file
- // without reading the header.
- text += "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n"
-
- // Go function header.
- outDecl := ""
- if len(out) > 0 {
- outDecl = fmt.Sprintf(" (%s)", strings.Join(out, ", "))
- }
- text += fmt.Sprintf("func %s(%s)%s {\n", funct, strings.Join(in, ", "), outDecl)
-
- // Check if err return available
- errvar := ""
- for _, param := range out {
- p := parseParam(param)
- if p.Type == "error" {
- errvar = p.Name
- break
- }
- }
-
- // Prepare arguments to Syscall.
- var args []string
- n := 0
- for _, param := range in {
- p := parseParam(param)
- if regexp.MustCompile(`^\*`).FindStringSubmatch(p.Type) != nil {
- args = append(args, "uintptr(unsafe.Pointer("+p.Name+"))")
- } else if p.Type == "string" && errvar != "" {
- text += fmt.Sprintf("\tvar _p%d *byte\n", n)
- text += fmt.Sprintf("\t_p%d, %s = BytePtrFromString(%s)\n", n, errvar, p.Name)
- text += fmt.Sprintf("\tif %s != nil {\n\t\treturn\n\t}\n", errvar)
- args = append(args, fmt.Sprintf("uintptr(unsafe.Pointer(_p%d))", n))
- n++
- } else if p.Type == "string" {
- fmt.Fprintf(os.Stderr, path+":"+funct+" uses string arguments, but has no error return\n")
- text += fmt.Sprintf("\tvar _p%d *byte\n", n)
- text += fmt.Sprintf("\t_p%d, _ = BytePtrFromString(%s)\n", n, p.Name)
- args = append(args, fmt.Sprintf("uintptr(unsafe.Pointer(_p%d))", n))
- n++
- } else if regexp.MustCompile(`^\[\](.*)`).FindStringSubmatch(p.Type) != nil {
- // Convert slice into pointer, length.
- // Have to be careful not to take address of &a[0] if len == 0:
- // pass dummy pointer in that case.
- // Used to pass nil, but some OSes or simulators reject write(fd, nil, 0).
- text += fmt.Sprintf("\tvar _p%d unsafe.Pointer\n", n)
- text += fmt.Sprintf("\tif len(%s) > 0 {\n\t\t_p%d = unsafe.Pointer(&%s[0])\n\t}", p.Name, n, p.Name)
- text += fmt.Sprintf(" else {\n\t\t_p%d = unsafe.Pointer(&_zero)\n\t}\n", n)
- args = append(args, fmt.Sprintf("uintptr(_p%d)", n), fmt.Sprintf("uintptr(len(%s))", p.Name))
- n++
- } else if p.Type == "int64" && (*openbsd || *netbsd) {
- args = append(args, "0")
- if endianness == "big-endian" {
- args = append(args, fmt.Sprintf("uintptr(%s>>32)", p.Name), fmt.Sprintf("uintptr(%s)", p.Name))
- } else if endianness == "little-endian" {
- args = append(args, fmt.Sprintf("uintptr(%s)", p.Name), fmt.Sprintf("uintptr(%s>>32)", p.Name))
- } else {
- args = append(args, fmt.Sprintf("uintptr(%s)", p.Name))
- }
- } else if p.Type == "int64" && *dragonfly {
- if regexp.MustCompile(`^(?i)extp(read|write)`).FindStringSubmatch(funct) == nil {
- args = append(args, "0")
- }
- if endianness == "big-endian" {
- args = append(args, fmt.Sprintf("uintptr(%s>>32)", p.Name), fmt.Sprintf("uintptr(%s)", p.Name))
- } else if endianness == "little-endian" {
- args = append(args, fmt.Sprintf("uintptr(%s)", p.Name), fmt.Sprintf("uintptr(%s>>32)", p.Name))
- } else {
- args = append(args, fmt.Sprintf("uintptr(%s)", p.Name))
- }
- } else if (p.Type == "int64" || p.Type == "uint64") && endianness != "" {
- if len(args)%2 == 1 && *arm {
- // arm abi specifies 64-bit argument uses
- // (even, odd) pair
- args = append(args, "0")
- }
- if endianness == "big-endian" {
- args = append(args, fmt.Sprintf("uintptr(%s>>32)", p.Name), fmt.Sprintf("uintptr(%s)", p.Name))
- } else {
- args = append(args, fmt.Sprintf("uintptr(%s)", p.Name), fmt.Sprintf("uintptr(%s>>32)", p.Name))
- }
- } else {
- args = append(args, fmt.Sprintf("uintptr(%s)", p.Name))
- }
- }
-
- // Determine which form to use; pad args with zeros.
- asm := "Syscall"
- if nonblock != nil {
- if errvar == "" && goos == "linux" {
- asm = "RawSyscallNoError"
- } else {
- asm = "RawSyscall"
- }
- } else {
- if errvar == "" && goos == "linux" {
- asm = "SyscallNoError"
- }
- }
- if len(args) <= 3 {
- for len(args) < 3 {
- args = append(args, "0")
- }
- } else if len(args) <= 6 {
- asm += "6"
- for len(args) < 6 {
- args = append(args, "0")
- }
- } else if len(args) <= 9 {
- asm += "9"
- for len(args) < 9 {
- args = append(args, "0")
- }
- } else {
- fmt.Fprintf(os.Stderr, "%s:%s too many arguments to system call\n", path, funct)
- }
-
- // System call number.
- if sysname == "" {
- sysname = "SYS_" + funct
- sysname = regexp.MustCompile(`([a-z])([A-Z])`).ReplaceAllString(sysname, `${1}_$2`)
- sysname = strings.ToUpper(sysname)
- }
-
- var libcFn string
- if libc {
- asm = "syscall_" + strings.ToLower(asm[:1]) + asm[1:] // internal syscall call
- sysname = strings.TrimPrefix(sysname, "SYS_") // remove SYS_
- sysname = strings.ToLower(sysname) // lowercase
- if sysname == "getdirentries64" {
- // Special case - libSystem name and
- // raw syscall name don't match.
- sysname = "__getdirentries64"
- }
- libcFn = sysname
- sysname = "funcPC(libc_" + sysname + "_trampoline)"
- }
-
- // Actual call.
- arglist := strings.Join(args, ", ")
- call := fmt.Sprintf("%s(%s, %s)", asm, sysname, arglist)
-
- // Assign return values.
- body := ""
- ret := []string{"_", "_", "_"}
- doErrno := false
- for i := 0; i < len(out); i++ {
- p := parseParam(out[i])
- reg := ""
- if p.Name == "err" && !*plan9 {
- reg = "e1"
- ret[2] = reg
- doErrno = true
- } else if p.Name == "err" && *plan9 {
- ret[0] = "r0"
- ret[2] = "e1"
- break
- } else {
- reg = fmt.Sprintf("r%d", i)
- ret[i] = reg
- }
- if p.Type == "bool" {
- reg = fmt.Sprintf("%s != 0", reg)
- }
- if p.Type == "int64" && endianness != "" {
- // 64-bit number in r1:r0 or r0:r1.
- if i+2 > len(out) {
- fmt.Fprintf(os.Stderr, "%s:%s not enough registers for int64 return\n", path, funct)
- }
- if endianness == "big-endian" {
- reg = fmt.Sprintf("int64(r%d)<<32 | int64(r%d)", i, i+1)
- } else {
- reg = fmt.Sprintf("int64(r%d)<<32 | int64(r%d)", i+1, i)
- }
- ret[i] = fmt.Sprintf("r%d", i)
- ret[i+1] = fmt.Sprintf("r%d", i+1)
- }
- if reg != "e1" || *plan9 {
- body += fmt.Sprintf("\t%s = %s(%s)\n", p.Name, p.Type, reg)
- }
- }
- if ret[0] == "_" && ret[1] == "_" && ret[2] == "_" {
- text += fmt.Sprintf("\t%s\n", call)
- } else {
- if errvar == "" && goos == "linux" {
- // raw syscall without error on Linux, see golang.org/issue/22924
- text += fmt.Sprintf("\t%s, %s := %s\n", ret[0], ret[1], call)
- } else {
- text += fmt.Sprintf("\t%s, %s, %s := %s\n", ret[0], ret[1], ret[2], call)
- }
- }
- text += body
-
- if *plan9 && ret[2] == "e1" {
- text += "\tif int32(r0) == -1 {\n"
- text += "\t\terr = e1\n"
- text += "\t}\n"
- } else if doErrno {
- text += "\tif e1 != 0 {\n"
- text += "\t\terr = errnoErr(e1)\n"
- text += "\t}\n"
- }
- text += "\treturn\n"
- text += "}\n\n"
-
- if libc && !trampolines[libcFn] {
- // some system calls share a trampoline, like read and readlen.
- trampolines[libcFn] = true
- // Declare assembly trampoline.
- text += fmt.Sprintf("func libc_%s_trampoline()\n", libcFn)
- // Assembly trampoline calls the libc_* function, which this magic
- // redirects to use the function from libSystem.
- text += fmt.Sprintf("//go:linkname libc_%s libc_%s\n", libcFn, libcFn)
- text += fmt.Sprintf("//go:cgo_import_dynamic libc_%s %s \"/usr/lib/libSystem.B.dylib\"\n", libcFn, libcFn)
- text += "\n"
- }
- }
- if err := s.Err(); err != nil {
- fmt.Fprintf(os.Stderr, err.Error())
- os.Exit(1)
- }
- file.Close()
- }
- fmt.Printf(srcTemplate, cmdLine(), buildTags(), text)
-}
-
-const srcTemplate = `// %s
-// Code generated by the command above; see README.md. DO NOT EDIT.
-
-// +build %s
-
-package unix
-
-import (
- "syscall"
- "unsafe"
-)
-
-var _ syscall.Errno
-
-%s
-`
diff --git a/vendor/golang.org/x/sys/unix/mksyscall_aix_ppc.go b/vendor/golang.org/x/sys/unix/mksyscall_aix_ppc.go
deleted file mode 100644
index 3be3cdf..0000000
--- a/vendor/golang.org/x/sys/unix/mksyscall_aix_ppc.go
+++ /dev/null
@@ -1,415 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-/*
-This program reads a file containing function prototypes
-(like syscall_aix.go) and generates system call bodies.
-The prototypes are marked by lines beginning with "//sys"
-and read like func declarations if //sys is replaced by func, but:
- * The parameter lists must give a name for each argument.
- This includes return parameters.
- * The parameter lists must give a type for each argument:
- the (x, y, z int) shorthand is not allowed.
- * If the return parameter is an error number, it must be named err.
- * If go func name needs to be different than its libc name,
- * or the function is not in libc, name could be specified
- * at the end, after "=" sign, like
- //sys getsockopt(s int, level int, name int, val uintptr, vallen *_Socklen) (err error) = libsocket.getsockopt
-*/
-package main
-
-import (
- "bufio"
- "flag"
- "fmt"
- "os"
- "regexp"
- "strings"
-)
-
-var (
- b32 = flag.Bool("b32", false, "32bit big-endian")
- l32 = flag.Bool("l32", false, "32bit little-endian")
- aix = flag.Bool("aix", false, "aix")
- tags = flag.String("tags", "", "build tags")
-)
-
-// cmdLine returns this programs's commandline arguments
-func cmdLine() string {
- return "go run mksyscall_aix_ppc.go " + strings.Join(os.Args[1:], " ")
-}
-
-// buildTags returns build tags
-func buildTags() string {
- return *tags
-}
-
-// Param is function parameter
-type Param struct {
- Name string
- Type string
-}
-
-// usage prints the program usage
-func usage() {
- fmt.Fprintf(os.Stderr, "usage: go run mksyscall_aix_ppc.go [-b32 | -l32] [-tags x,y] [file ...]\n")
- os.Exit(1)
-}
-
-// parseParamList parses parameter list and returns a slice of parameters
-func parseParamList(list string) []string {
- list = strings.TrimSpace(list)
- if list == "" {
- return []string{}
- }
- return regexp.MustCompile(`\s*,\s*`).Split(list, -1)
-}
-
-// parseParam splits a parameter into name and type
-func parseParam(p string) Param {
- ps := regexp.MustCompile(`^(\S*) (\S*)$`).FindStringSubmatch(p)
- if ps == nil {
- fmt.Fprintf(os.Stderr, "malformed parameter: %s\n", p)
- os.Exit(1)
- }
- return Param{ps[1], ps[2]}
-}
-
-func main() {
- flag.Usage = usage
- flag.Parse()
- if len(flag.Args()) <= 0 {
- fmt.Fprintf(os.Stderr, "no files to parse provided\n")
- usage()
- }
-
- endianness := ""
- if *b32 {
- endianness = "big-endian"
- } else if *l32 {
- endianness = "little-endian"
- }
-
- pack := ""
- text := ""
- cExtern := "/*\n#include <stdint.h>\n#include <stddef.h>\n"
- for _, path := range flag.Args() {
- file, err := os.Open(path)
- if err != nil {
- fmt.Fprintf(os.Stderr, err.Error())
- os.Exit(1)
- }
- s := bufio.NewScanner(file)
- for s.Scan() {
- t := s.Text()
- t = strings.TrimSpace(t)
- t = regexp.MustCompile(`\s+`).ReplaceAllString(t, ` `)
- if p := regexp.MustCompile(`^package (\S+)$`).FindStringSubmatch(t); p != nil && pack == "" {
- pack = p[1]
- }
- nonblock := regexp.MustCompile(`^\/\/sysnb `).FindStringSubmatch(t)
- if regexp.MustCompile(`^\/\/sys `).FindStringSubmatch(t) == nil && nonblock == nil {
- continue
- }
-
- // Line must be of the form
- // func Open(path string, mode int, perm int) (fd int, err error)
- // Split into name, in params, out params.
- f := regexp.MustCompile(`^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*(?:(\w*)\.)?(\w*))?$`).FindStringSubmatch(t)
- if f == nil {
- fmt.Fprintf(os.Stderr, "%s:%s\nmalformed //sys declaration\n", path, t)
- os.Exit(1)
- }
- funct, inps, outps, modname, sysname := f[2], f[3], f[4], f[5], f[6]
-
- // Split argument lists on comma.
- in := parseParamList(inps)
- out := parseParamList(outps)
-
- inps = strings.Join(in, ", ")
- outps = strings.Join(out, ", ")
-
- // Try in vain to keep people from editing this file.
- // The theory is that they jump into the middle of the file
- // without reading the header.
- text += "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n"
-
- // Check if value return, err return available
- errvar := ""
- retvar := ""
- rettype := ""
- for _, param := range out {
- p := parseParam(param)
- if p.Type == "error" {
- errvar = p.Name
- } else {
- retvar = p.Name
- rettype = p.Type
- }
- }
-
- // System call name.
- if sysname == "" {
- sysname = funct
- }
- sysname = regexp.MustCompile(`([a-z])([A-Z])`).ReplaceAllString(sysname, `${1}_$2`)
- sysname = strings.ToLower(sysname) // All libc functions are lowercase.
-
- cRettype := ""
- if rettype == "unsafe.Pointer" {
- cRettype = "uintptr_t"
- } else if rettype == "uintptr" {
- cRettype = "uintptr_t"
- } else if regexp.MustCompile(`^_`).FindStringSubmatch(rettype) != nil {
- cRettype = "uintptr_t"
- } else if rettype == "int" {
- cRettype = "int"
- } else if rettype == "int32" {
- cRettype = "int"
- } else if rettype == "int64" {
- cRettype = "long long"
- } else if rettype == "uint32" {
- cRettype = "unsigned int"
- } else if rettype == "uint64" {
- cRettype = "unsigned long long"
- } else {
- cRettype = "int"
- }
- if sysname == "exit" {
- cRettype = "void"
- }
-
- // Change p.Types to c
- var cIn []string
- for _, param := range in {
- p := parseParam(param)
- if regexp.MustCompile(`^\*`).FindStringSubmatch(p.Type) != nil {
- cIn = append(cIn, "uintptr_t")
- } else if p.Type == "string" {
- cIn = append(cIn, "uintptr_t")
- } else if regexp.MustCompile(`^\[\](.*)`).FindStringSubmatch(p.Type) != nil {
- cIn = append(cIn, "uintptr_t", "size_t")
- } else if p.Type == "unsafe.Pointer" {
- cIn = append(cIn, "uintptr_t")
- } else if p.Type == "uintptr" {
- cIn = append(cIn, "uintptr_t")
- } else if regexp.MustCompile(`^_`).FindStringSubmatch(p.Type) != nil {
- cIn = append(cIn, "uintptr_t")
- } else if p.Type == "int" {
- cIn = append(cIn, "int")
- } else if p.Type == "int32" {
- cIn = append(cIn, "int")
- } else if p.Type == "int64" {
- cIn = append(cIn, "long long")
- } else if p.Type == "uint32" {
- cIn = append(cIn, "unsigned int")
- } else if p.Type == "uint64" {
- cIn = append(cIn, "unsigned long long")
- } else {
- cIn = append(cIn, "int")
- }
- }
-
- if funct != "fcntl" && funct != "FcntlInt" && funct != "readlen" && funct != "writelen" {
- if sysname == "select" {
- // select is a keyword of Go. Its name is
- // changed to c_select.
- cExtern += "#define c_select select\n"
- }
- // Imports of system calls from libc
- cExtern += fmt.Sprintf("%s %s", cRettype, sysname)
- cIn := strings.Join(cIn, ", ")
- cExtern += fmt.Sprintf("(%s);\n", cIn)
- }
-
- // So file name.
- if *aix {
- if modname == "" {
- modname = "libc.a/shr_64.o"
- } else {
- fmt.Fprintf(os.Stderr, "%s: only syscall using libc are available\n", funct)
- os.Exit(1)
- }
- }
-
- strconvfunc := "C.CString"
-
- // Go function header.
- if outps != "" {
- outps = fmt.Sprintf(" (%s)", outps)
- }
- if text != "" {
- text += "\n"
- }
-
- text += fmt.Sprintf("func %s(%s)%s {\n", funct, strings.Join(in, ", "), outps)
-
- // Prepare arguments to Syscall.
- var args []string
- n := 0
- argN := 0
- for _, param := range in {
- p := parseParam(param)
- if regexp.MustCompile(`^\*`).FindStringSubmatch(p.Type) != nil {
- args = append(args, "C.uintptr_t(uintptr(unsafe.Pointer("+p.Name+")))")
- } else if p.Type == "string" && errvar != "" {
- text += fmt.Sprintf("\t_p%d := uintptr(unsafe.Pointer(%s(%s)))\n", n, strconvfunc, p.Name)
- args = append(args, fmt.Sprintf("C.uintptr_t(_p%d)", n))
- n++
- } else if p.Type == "string" {
- fmt.Fprintf(os.Stderr, path+":"+funct+" uses string arguments, but has no error return\n")
- text += fmt.Sprintf("\t_p%d := uintptr(unsafe.Pointer(%s(%s)))\n", n, strconvfunc, p.Name)
- args = append(args, fmt.Sprintf("C.uintptr_t(_p%d)", n))
- n++
- } else if m := regexp.MustCompile(`^\[\](.*)`).FindStringSubmatch(p.Type); m != nil {
- // Convert slice into pointer, length.
- // Have to be careful not to take address of &a[0] if len == 0:
- // pass nil in that case.
- text += fmt.Sprintf("\tvar _p%d *%s\n", n, m[1])
- text += fmt.Sprintf("\tif len(%s) > 0 {\n\t\t_p%d = &%s[0]\n\t}\n", p.Name, n, p.Name)
- args = append(args, fmt.Sprintf("C.uintptr_t(uintptr(unsafe.Pointer(_p%d)))", n))
- n++
- text += fmt.Sprintf("\tvar _p%d int\n", n)
- text += fmt.Sprintf("\t_p%d = len(%s)\n", n, p.Name)
- args = append(args, fmt.Sprintf("C.size_t(_p%d)", n))
- n++
- } else if p.Type == "int64" && endianness != "" {
- if endianness == "big-endian" {
- args = append(args, fmt.Sprintf("uintptr(%s>>32)", p.Name), fmt.Sprintf("uintptr(%s)", p.Name))
- } else {
- args = append(args, fmt.Sprintf("uintptr(%s)", p.Name), fmt.Sprintf("uintptr(%s>>32)", p.Name))
- }
- n++
- } else if p.Type == "bool" {
- text += fmt.Sprintf("\tvar _p%d uint32\n", n)
- text += fmt.Sprintf("\tif %s {\n\t\t_p%d = 1\n\t} else {\n\t\t_p%d = 0\n\t}\n", p.Name, n, n)
- args = append(args, fmt.Sprintf("_p%d", n))
- } else if regexp.MustCompile(`^_`).FindStringSubmatch(p.Type) != nil {
- args = append(args, fmt.Sprintf("C.uintptr_t(uintptr(%s))", p.Name))
- } else if p.Type == "unsafe.Pointer" {
- args = append(args, fmt.Sprintf("C.uintptr_t(uintptr(%s))", p.Name))
- } else if p.Type == "int" {
- if (argN == 2) && ((funct == "readlen") || (funct == "writelen")) {
- args = append(args, fmt.Sprintf("C.size_t(%s)", p.Name))
- } else if argN == 0 && funct == "fcntl" {
- args = append(args, fmt.Sprintf("C.uintptr_t(%s)", p.Name))
- } else if (argN == 2) && ((funct == "fcntl") || (funct == "FcntlInt")) {
- args = append(args, fmt.Sprintf("C.uintptr_t(%s)", p.Name))
- } else {
- args = append(args, fmt.Sprintf("C.int(%s)", p.Name))
- }
- } else if p.Type == "int32" {
- args = append(args, fmt.Sprintf("C.int(%s)", p.Name))
- } else if p.Type == "int64" {
- args = append(args, fmt.Sprintf("C.longlong(%s)", p.Name))
- } else if p.Type == "uint32" {
- args = append(args, fmt.Sprintf("C.uint(%s)", p.Name))
- } else if p.Type == "uint64" {
- args = append(args, fmt.Sprintf("C.ulonglong(%s)", p.Name))
- } else if p.Type == "uintptr" {
- args = append(args, fmt.Sprintf("C.uintptr_t(%s)", p.Name))
- } else {
- args = append(args, fmt.Sprintf("C.int(%s)", p.Name))
- }
- argN++
- }
-
- // Actual call.
- arglist := strings.Join(args, ", ")
- call := ""
- if sysname == "exit" {
- if errvar != "" {
- call += "er :="
- } else {
- call += ""
- }
- } else if errvar != "" {
- call += "r0,er :="
- } else if retvar != "" {
- call += "r0,_ :="
- } else {
- call += ""
- }
- if sysname == "select" {
- // select is a keyword of Go. Its name is
- // changed to c_select.
- call += fmt.Sprintf("C.c_%s(%s)", sysname, arglist)
- } else {
- call += fmt.Sprintf("C.%s(%s)", sysname, arglist)
- }
-
- // Assign return values.
- body := ""
- for i := 0; i < len(out); i++ {
- p := parseParam(out[i])
- reg := ""
- if p.Name == "err" {
- reg = "e1"
- } else {
- reg = "r0"
- }
- if reg != "e1" {
- body += fmt.Sprintf("\t%s = %s(%s)\n", p.Name, p.Type, reg)
- }
- }
-
- // verify return
- if sysname != "exit" && errvar != "" {
- if regexp.MustCompile(`^uintptr`).FindStringSubmatch(cRettype) != nil {
- body += "\tif (uintptr(r0) ==^uintptr(0) && er != nil) {\n"
- body += fmt.Sprintf("\t\t%s = er\n", errvar)
- body += "\t}\n"
- } else {
- body += "\tif (r0 ==-1 && er != nil) {\n"
- body += fmt.Sprintf("\t\t%s = er\n", errvar)
- body += "\t}\n"
- }
- } else if errvar != "" {
- body += "\tif (er != nil) {\n"
- body += fmt.Sprintf("\t\t%s = er\n", errvar)
- body += "\t}\n"
- }
-
- text += fmt.Sprintf("\t%s\n", call)
- text += body
-
- text += "\treturn\n"
- text += "}\n"
- }
- if err := s.Err(); err != nil {
- fmt.Fprintf(os.Stderr, err.Error())
- os.Exit(1)
- }
- file.Close()
- }
- imp := ""
- if pack != "unix" {
- imp = "import \"golang.org/x/sys/unix\"\n"
-
- }
- fmt.Printf(srcTemplate, cmdLine(), buildTags(), pack, cExtern, imp, text)
-}
-
-const srcTemplate = `// %s
-// Code generated by the command above; see README.md. DO NOT EDIT.
-
-// +build %s
-
-package %s
-
-
-%s
-*/
-import "C"
-import (
- "unsafe"
-)
-
-
-%s
-
-%s
-`
diff --git a/vendor/golang.org/x/sys/unix/mksyscall_aix_ppc64.go b/vendor/golang.org/x/sys/unix/mksyscall_aix_ppc64.go
deleted file mode 100644
index c960099..0000000
--- a/vendor/golang.org/x/sys/unix/mksyscall_aix_ppc64.go
+++ /dev/null
@@ -1,614 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-/*
-This program reads a file containing function prototypes
-(like syscall_aix.go) and generates system call bodies.
-The prototypes are marked by lines beginning with "//sys"
-and read like func declarations if //sys is replaced by func, but:
- * The parameter lists must give a name for each argument.
- This includes return parameters.
- * The parameter lists must give a type for each argument:
- the (x, y, z int) shorthand is not allowed.
- * If the return parameter is an error number, it must be named err.
- * If go func name needs to be different than its libc name,
- * or the function is not in libc, name could be specified
- * at the end, after "=" sign, like
- //sys getsockopt(s int, level int, name int, val uintptr, vallen *_Socklen) (err error) = libsocket.getsockopt
-
-
-This program will generate three files and handle both gc and gccgo implementation:
- - zsyscall_aix_ppc64.go: the common part of each implementation (error handler, pointer creation)
- - zsyscall_aix_ppc64_gc.go: gc part with //go_cgo_import_dynamic and a call to syscall6
- - zsyscall_aix_ppc64_gccgo.go: gccgo part with C function and conversion to C type.
-
- The generated code looks like this
-
-zsyscall_aix_ppc64.go
-func asyscall(...) (n int, err error) {
- // Pointer Creation
- r1, e1 := callasyscall(...)
- // Type Conversion
- // Error Handler
- return
-}
-
-zsyscall_aix_ppc64_gc.go
-//go:cgo_import_dynamic libc_asyscall asyscall "libc.a/shr_64.o"
-//go:linkname libc_asyscall libc_asyscall
-var asyscall syscallFunc
-
-func callasyscall(...) (r1 uintptr, e1 Errno) {
- r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_asyscall)), "nb_args", ... )
- return
-}
-
-zsyscall_aix_ppc64_ggcgo.go
-
-// int asyscall(...)
-
-import "C"
-
-func callasyscall(...) (r1 uintptr, e1 Errno) {
- r1 = uintptr(C.asyscall(...))
- e1 = syscall.GetErrno()
- return
-}
-*/
-
-package main
-
-import (
- "bufio"
- "flag"
- "fmt"
- "io/ioutil"
- "os"
- "regexp"
- "strings"
-)
-
-var (
- b32 = flag.Bool("b32", false, "32bit big-endian")
- l32 = flag.Bool("l32", false, "32bit little-endian")
- aix = flag.Bool("aix", false, "aix")
- tags = flag.String("tags", "", "build tags")
-)
-
-// cmdLine returns this programs's commandline arguments
-func cmdLine() string {
- return "go run mksyscall_aix_ppc64.go " + strings.Join(os.Args[1:], " ")
-}
-
-// buildTags returns build tags
-func buildTags() string {
- return *tags
-}
-
-// Param is function parameter
-type Param struct {
- Name string
- Type string
-}
-
-// usage prints the program usage
-func usage() {
- fmt.Fprintf(os.Stderr, "usage: go run mksyscall_aix_ppc64.go [-b32 | -l32] [-tags x,y] [file ...]\n")
- os.Exit(1)
-}
-
-// parseParamList parses parameter list and returns a slice of parameters
-func parseParamList(list string) []string {
- list = strings.TrimSpace(list)
- if list == "" {
- return []string{}
- }
- return regexp.MustCompile(`\s*,\s*`).Split(list, -1)
-}
-
-// parseParam splits a parameter into name and type
-func parseParam(p string) Param {
- ps := regexp.MustCompile(`^(\S*) (\S*)$`).FindStringSubmatch(p)
- if ps == nil {
- fmt.Fprintf(os.Stderr, "malformed parameter: %s\n", p)
- os.Exit(1)
- }
- return Param{ps[1], ps[2]}
-}
-
-func main() {
- flag.Usage = usage
- flag.Parse()
- if len(flag.Args()) <= 0 {
- fmt.Fprintf(os.Stderr, "no files to parse provided\n")
- usage()
- }
-
- endianness := ""
- if *b32 {
- endianness = "big-endian"
- } else if *l32 {
- endianness = "little-endian"
- }
-
- pack := ""
- // GCCGO
- textgccgo := ""
- cExtern := "/*\n#include <stdint.h>\n"
- // GC
- textgc := ""
- dynimports := ""
- linknames := ""
- var vars []string
- // COMMON
- textcommon := ""
- for _, path := range flag.Args() {
- file, err := os.Open(path)
- if err != nil {
- fmt.Fprintf(os.Stderr, err.Error())
- os.Exit(1)
- }
- s := bufio.NewScanner(file)
- for s.Scan() {
- t := s.Text()
- t = strings.TrimSpace(t)
- t = regexp.MustCompile(`\s+`).ReplaceAllString(t, ` `)
- if p := regexp.MustCompile(`^package (\S+)$`).FindStringSubmatch(t); p != nil && pack == "" {
- pack = p[1]
- }
- nonblock := regexp.MustCompile(`^\/\/sysnb `).FindStringSubmatch(t)
- if regexp.MustCompile(`^\/\/sys `).FindStringSubmatch(t) == nil && nonblock == nil {
- continue
- }
-
- // Line must be of the form
- // func Open(path string, mode int, perm int) (fd int, err error)
- // Split into name, in params, out params.
- f := regexp.MustCompile(`^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*(?:(\w*)\.)?(\w*))?$`).FindStringSubmatch(t)
- if f == nil {
- fmt.Fprintf(os.Stderr, "%s:%s\nmalformed //sys declaration\n", path, t)
- os.Exit(1)
- }
- funct, inps, outps, modname, sysname := f[2], f[3], f[4], f[5], f[6]
-
- // Split argument lists on comma.
- in := parseParamList(inps)
- out := parseParamList(outps)
-
- inps = strings.Join(in, ", ")
- outps = strings.Join(out, ", ")
-
- if sysname == "" {
- sysname = funct
- }
-
- onlyCommon := false
- if funct == "readlen" || funct == "writelen" || funct == "FcntlInt" || funct == "FcntlFlock" {
- // This function call another syscall which is already implemented.
- // Therefore, the gc and gccgo part must not be generated.
- onlyCommon = true
- }
-
- // Try in vain to keep people from editing this file.
- // The theory is that they jump into the middle of the file
- // without reading the header.
-
- textcommon += "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n"
- if !onlyCommon {
- textgccgo += "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n"
- textgc += "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n"
- }
-
- // Check if value return, err return available
- errvar := ""
- rettype := ""
- for _, param := range out {
- p := parseParam(param)
- if p.Type == "error" {
- errvar = p.Name
- } else {
- rettype = p.Type
- }
- }
-
- sysname = regexp.MustCompile(`([a-z])([A-Z])`).ReplaceAllString(sysname, `${1}_$2`)
- sysname = strings.ToLower(sysname) // All libc functions are lowercase.
-
- // GCCGO Prototype return type
- cRettype := ""
- if rettype == "unsafe.Pointer" {
- cRettype = "uintptr_t"
- } else if rettype == "uintptr" {
- cRettype = "uintptr_t"
- } else if regexp.MustCompile(`^_`).FindStringSubmatch(rettype) != nil {
- cRettype = "uintptr_t"
- } else if rettype == "int" {
- cRettype = "int"
- } else if rettype == "int32" {
- cRettype = "int"
- } else if rettype == "int64" {
- cRettype = "long long"
- } else if rettype == "uint32" {
- cRettype = "unsigned int"
- } else if rettype == "uint64" {
- cRettype = "unsigned long long"
- } else {
- cRettype = "int"
- }
- if sysname == "exit" {
- cRettype = "void"
- }
-
- // GCCGO Prototype arguments type
- var cIn []string
- for i, param := range in {
- p := parseParam(param)
- if regexp.MustCompile(`^\*`).FindStringSubmatch(p.Type) != nil {
- cIn = append(cIn, "uintptr_t")
- } else if p.Type == "string" {
- cIn = append(cIn, "uintptr_t")
- } else if regexp.MustCompile(`^\[\](.*)`).FindStringSubmatch(p.Type) != nil {
- cIn = append(cIn, "uintptr_t", "size_t")
- } else if p.Type == "unsafe.Pointer" {
- cIn = append(cIn, "uintptr_t")
- } else if p.Type == "uintptr" {
- cIn = append(cIn, "uintptr_t")
- } else if regexp.MustCompile(`^_`).FindStringSubmatch(p.Type) != nil {
- cIn = append(cIn, "uintptr_t")
- } else if p.Type == "int" {
- if (i == 0 || i == 2) && funct == "fcntl" {
- // These fcntl arguments needs to be uintptr to be able to call FcntlInt and FcntlFlock
- cIn = append(cIn, "uintptr_t")
- } else {
- cIn = append(cIn, "int")
- }
-
- } else if p.Type == "int32" {
- cIn = append(cIn, "int")
- } else if p.Type == "int64" {
- cIn = append(cIn, "long long")
- } else if p.Type == "uint32" {
- cIn = append(cIn, "unsigned int")
- } else if p.Type == "uint64" {
- cIn = append(cIn, "unsigned long long")
- } else {
- cIn = append(cIn, "int")
- }
- }
-
- if !onlyCommon {
- // GCCGO Prototype Generation
- // Imports of system calls from libc
- if sysname == "select" {
- // select is a keyword of Go. Its name is
- // changed to c_select.
- cExtern += "#define c_select select\n"
- }
- cExtern += fmt.Sprintf("%s %s", cRettype, sysname)
- cIn := strings.Join(cIn, ", ")
- cExtern += fmt.Sprintf("(%s);\n", cIn)
- }
- // GC Library name
- if modname == "" {
- modname = "libc.a/shr_64.o"
- } else {
- fmt.Fprintf(os.Stderr, "%s: only syscall using libc are available\n", funct)
- os.Exit(1)
- }
- sysvarname := fmt.Sprintf("libc_%s", sysname)
-
- if !onlyCommon {
- // GC Runtime import of function to allow cross-platform builds.
- dynimports += fmt.Sprintf("//go:cgo_import_dynamic %s %s \"%s\"\n", sysvarname, sysname, modname)
- // GC Link symbol to proc address variable.
- linknames += fmt.Sprintf("//go:linkname %s %s\n", sysvarname, sysvarname)
- // GC Library proc address variable.
- vars = append(vars, sysvarname)
- }
-
- strconvfunc := "BytePtrFromString"
- strconvtype := "*byte"
-
- // Go function header.
- if outps != "" {
- outps = fmt.Sprintf(" (%s)", outps)
- }
- if textcommon != "" {
- textcommon += "\n"
- }
-
- textcommon += fmt.Sprintf("func %s(%s)%s {\n", funct, strings.Join(in, ", "), outps)
-
- // Prepare arguments tocall.
- var argscommon []string // Arguments in the common part
- var argscall []string // Arguments for call prototype
- var argsgc []string // Arguments for gc call (with syscall6)
- var argsgccgo []string // Arguments for gccgo call (with C.name_of_syscall)
- n := 0
- argN := 0
- for _, param := range in {
- p := parseParam(param)
- if regexp.MustCompile(`^\*`).FindStringSubmatch(p.Type) != nil {
- argscommon = append(argscommon, fmt.Sprintf("uintptr(unsafe.Pointer(%s))", p.Name))
- argscall = append(argscall, fmt.Sprintf("%s uintptr", p.Name))
- argsgc = append(argsgc, p.Name)
- argsgccgo = append(argsgccgo, fmt.Sprintf("C.uintptr_t(%s)", p.Name))
- } else if p.Type == "string" && errvar != "" {
- textcommon += fmt.Sprintf("\tvar _p%d %s\n", n, strconvtype)
- textcommon += fmt.Sprintf("\t_p%d, %s = %s(%s)\n", n, errvar, strconvfunc, p.Name)
- textcommon += fmt.Sprintf("\tif %s != nil {\n\t\treturn\n\t}\n", errvar)
-
- argscommon = append(argscommon, fmt.Sprintf("uintptr(unsafe.Pointer(_p%d))", n))
- argscall = append(argscall, fmt.Sprintf("_p%d uintptr ", n))
- argsgc = append(argsgc, fmt.Sprintf("_p%d", n))
- argsgccgo = append(argsgccgo, fmt.Sprintf("C.uintptr_t(_p%d)", n))
- n++
- } else if p.Type == "string" {
- fmt.Fprintf(os.Stderr, path+":"+funct+" uses string arguments, but has no error return\n")
- textcommon += fmt.Sprintf("\tvar _p%d %s\n", n, strconvtype)
- textcommon += fmt.Sprintf("\t_p%d, %s = %s(%s)\n", n, errvar, strconvfunc, p.Name)
- textcommon += fmt.Sprintf("\tif %s != nil {\n\t\treturn\n\t}\n", errvar)
-
- argscommon = append(argscommon, fmt.Sprintf("uintptr(unsafe.Pointer(_p%d))", n))
- argscall = append(argscall, fmt.Sprintf("_p%d uintptr", n))
- argsgc = append(argsgc, fmt.Sprintf("_p%d", n))
- argsgccgo = append(argsgccgo, fmt.Sprintf("C.uintptr_t(_p%d)", n))
- n++
- } else if m := regexp.MustCompile(`^\[\](.*)`).FindStringSubmatch(p.Type); m != nil {
- // Convert slice into pointer, length.
- // Have to be careful not to take address of &a[0] if len == 0:
- // pass nil in that case.
- textcommon += fmt.Sprintf("\tvar _p%d *%s\n", n, m[1])
- textcommon += fmt.Sprintf("\tif len(%s) > 0 {\n\t\t_p%d = &%s[0]\n\t}\n", p.Name, n, p.Name)
- argscommon = append(argscommon, fmt.Sprintf("uintptr(unsafe.Pointer(_p%d))", n), fmt.Sprintf("len(%s)", p.Name))
- argscall = append(argscall, fmt.Sprintf("_p%d uintptr", n), fmt.Sprintf("_lenp%d int", n))
- argsgc = append(argsgc, fmt.Sprintf("_p%d", n), fmt.Sprintf("uintptr(_lenp%d)", n))
- argsgccgo = append(argsgccgo, fmt.Sprintf("C.uintptr_t(_p%d)", n), fmt.Sprintf("C.size_t(_lenp%d)", n))
- n++
- } else if p.Type == "int64" && endianness != "" {
- fmt.Fprintf(os.Stderr, path+":"+funct+" uses int64 with 32 bits mode. Case not yet implemented\n")
- } else if p.Type == "bool" {
- fmt.Fprintf(os.Stderr, path+":"+funct+" uses bool. Case not yet implemented\n")
- } else if regexp.MustCompile(`^_`).FindStringSubmatch(p.Type) != nil || p.Type == "unsafe.Pointer" {
- argscommon = append(argscommon, fmt.Sprintf("uintptr(%s)", p.Name))
- argscall = append(argscall, fmt.Sprintf("%s uintptr", p.Name))
- argsgc = append(argsgc, p.Name)
- argsgccgo = append(argsgccgo, fmt.Sprintf("C.uintptr_t(%s)", p.Name))
- } else if p.Type == "int" {
- if (argN == 0 || argN == 2) && ((funct == "fcntl") || (funct == "FcntlInt") || (funct == "FcntlFlock")) {
- // These fcntl arguments need to be uintptr to be able to call FcntlInt and FcntlFlock
- argscommon = append(argscommon, fmt.Sprintf("uintptr(%s)", p.Name))
- argscall = append(argscall, fmt.Sprintf("%s uintptr", p.Name))
- argsgc = append(argsgc, p.Name)
- argsgccgo = append(argsgccgo, fmt.Sprintf("C.uintptr_t(%s)", p.Name))
-
- } else {
- argscommon = append(argscommon, p.Name)
- argscall = append(argscall, fmt.Sprintf("%s int", p.Name))
- argsgc = append(argsgc, fmt.Sprintf("uintptr(%s)", p.Name))
- argsgccgo = append(argsgccgo, fmt.Sprintf("C.int(%s)", p.Name))
- }
- } else if p.Type == "int32" {
- argscommon = append(argscommon, p.Name)
- argscall = append(argscall, fmt.Sprintf("%s int32", p.Name))
- argsgc = append(argsgc, fmt.Sprintf("uintptr(%s)", p.Name))
- argsgccgo = append(argsgccgo, fmt.Sprintf("C.int(%s)", p.Name))
- } else if p.Type == "int64" {
- argscommon = append(argscommon, p.Name)
- argscall = append(argscall, fmt.Sprintf("%s int64", p.Name))
- argsgc = append(argsgc, fmt.Sprintf("uintptr(%s)", p.Name))
- argsgccgo = append(argsgccgo, fmt.Sprintf("C.longlong(%s)", p.Name))
- } else if p.Type == "uint32" {
- argscommon = append(argscommon, p.Name)
- argscall = append(argscall, fmt.Sprintf("%s uint32", p.Name))
- argsgc = append(argsgc, fmt.Sprintf("uintptr(%s)", p.Name))
- argsgccgo = append(argsgccgo, fmt.Sprintf("C.uint(%s)", p.Name))
- } else if p.Type == "uint64" {
- argscommon = append(argscommon, p.Name)
- argscall = append(argscall, fmt.Sprintf("%s uint64", p.Name))
- argsgc = append(argsgc, fmt.Sprintf("uintptr(%s)", p.Name))
- argsgccgo = append(argsgccgo, fmt.Sprintf("C.ulonglong(%s)", p.Name))
- } else if p.Type == "uintptr" {
- argscommon = append(argscommon, p.Name)
- argscall = append(argscall, fmt.Sprintf("%s uintptr", p.Name))
- argsgc = append(argsgc, p.Name)
- argsgccgo = append(argsgccgo, fmt.Sprintf("C.uintptr_t(%s)", p.Name))
- } else {
- argscommon = append(argscommon, fmt.Sprintf("int(%s)", p.Name))
- argscall = append(argscall, fmt.Sprintf("%s int", p.Name))
- argsgc = append(argsgc, fmt.Sprintf("uintptr(%s)", p.Name))
- argsgccgo = append(argsgccgo, fmt.Sprintf("C.int(%s)", p.Name))
- }
- argN++
- }
- nargs := len(argsgc)
-
- // COMMON function generation
- argscommonlist := strings.Join(argscommon, ", ")
- callcommon := fmt.Sprintf("call%s(%s)", sysname, argscommonlist)
- ret := []string{"_", "_"}
- body := ""
- doErrno := false
- for i := 0; i < len(out); i++ {
- p := parseParam(out[i])
- reg := ""
- if p.Name == "err" {
- reg = "e1"
- ret[1] = reg
- doErrno = true
- } else {
- reg = "r0"
- ret[0] = reg
- }
- if p.Type == "bool" {
- reg = fmt.Sprintf("%s != 0", reg)
- }
- if reg != "e1" {
- body += fmt.Sprintf("\t%s = %s(%s)\n", p.Name, p.Type, reg)
- }
- }
- if ret[0] == "_" && ret[1] == "_" {
- textcommon += fmt.Sprintf("\t%s\n", callcommon)
- } else {
- textcommon += fmt.Sprintf("\t%s, %s := %s\n", ret[0], ret[1], callcommon)
- }
- textcommon += body
-
- if doErrno {
- textcommon += "\tif e1 != 0 {\n"
- textcommon += "\t\terr = errnoErr(e1)\n"
- textcommon += "\t}\n"
- }
- textcommon += "\treturn\n"
- textcommon += "}\n"
-
- if onlyCommon {
- continue
- }
-
- // CALL Prototype
- callProto := fmt.Sprintf("func call%s(%s) (r1 uintptr, e1 Errno) {\n", sysname, strings.Join(argscall, ", "))
-
- // GC function generation
- asm := "syscall6"
- if nonblock != nil {
- asm = "rawSyscall6"
- }
-
- if len(argsgc) <= 6 {
- for len(argsgc) < 6 {
- argsgc = append(argsgc, "0")
- }
- } else {
- fmt.Fprintf(os.Stderr, "%s: too many arguments to system call", funct)
- os.Exit(1)
- }
- argsgclist := strings.Join(argsgc, ", ")
- callgc := fmt.Sprintf("%s(uintptr(unsafe.Pointer(&%s)), %d, %s)", asm, sysvarname, nargs, argsgclist)
-
- textgc += callProto
- textgc += fmt.Sprintf("\tr1, _, e1 = %s\n", callgc)
- textgc += "\treturn\n}\n"
-
- // GCCGO function generation
- argsgccgolist := strings.Join(argsgccgo, ", ")
- var callgccgo string
- if sysname == "select" {
- // select is a keyword of Go. Its name is
- // changed to c_select.
- callgccgo = fmt.Sprintf("C.c_%s(%s)", sysname, argsgccgolist)
- } else {
- callgccgo = fmt.Sprintf("C.%s(%s)", sysname, argsgccgolist)
- }
- textgccgo += callProto
- textgccgo += fmt.Sprintf("\tr1 = uintptr(%s)\n", callgccgo)
- textgccgo += "\te1 = syscall.GetErrno()\n"
- textgccgo += "\treturn\n}\n"
- }
- if err := s.Err(); err != nil {
- fmt.Fprintf(os.Stderr, err.Error())
- os.Exit(1)
- }
- file.Close()
- }
- imp := ""
- if pack != "unix" {
- imp = "import \"golang.org/x/sys/unix\"\n"
-
- }
-
- // Print zsyscall_aix_ppc64.go
- err := ioutil.WriteFile("zsyscall_aix_ppc64.go",
- []byte(fmt.Sprintf(srcTemplate1, cmdLine(), buildTags(), pack, imp, textcommon)),
- 0644)
- if err != nil {
- fmt.Fprintf(os.Stderr, err.Error())
- os.Exit(1)
- }
-
- // Print zsyscall_aix_ppc64_gc.go
- vardecls := "\t" + strings.Join(vars, ",\n\t")
- vardecls += " syscallFunc"
- err = ioutil.WriteFile("zsyscall_aix_ppc64_gc.go",
- []byte(fmt.Sprintf(srcTemplate2, cmdLine(), buildTags(), pack, imp, dynimports, linknames, vardecls, textgc)),
- 0644)
- if err != nil {
- fmt.Fprintf(os.Stderr, err.Error())
- os.Exit(1)
- }
-
- // Print zsyscall_aix_ppc64_gccgo.go
- err = ioutil.WriteFile("zsyscall_aix_ppc64_gccgo.go",
- []byte(fmt.Sprintf(srcTemplate3, cmdLine(), buildTags(), pack, cExtern, imp, textgccgo)),
- 0644)
- if err != nil {
- fmt.Fprintf(os.Stderr, err.Error())
- os.Exit(1)
- }
-}
-
-const srcTemplate1 = `// %s
-// Code generated by the command above; see README.md. DO NOT EDIT.
-
-// +build %s
-
-package %s
-
-import (
- "unsafe"
-)
-
-
-%s
-
-%s
-`
-const srcTemplate2 = `// %s
-// Code generated by the command above; see README.md. DO NOT EDIT.
-
-// +build %s
-// +build !gccgo
-
-package %s
-
-import (
- "unsafe"
-)
-%s
-%s
-%s
-type syscallFunc uintptr
-
-var (
-%s
-)
-
-// Implemented in runtime/syscall_aix.go.
-func rawSyscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
-func syscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
-
-%s
-`
-const srcTemplate3 = `// %s
-// Code generated by the command above; see README.md. DO NOT EDIT.
-
-// +build %s
-// +build gccgo
-
-package %s
-
-%s
-*/
-import "C"
-import (
- "syscall"
-)
-
-
-%s
-
-%s
-`
diff --git a/vendor/golang.org/x/sys/unix/mksyscall_solaris.go b/vendor/golang.org/x/sys/unix/mksyscall_solaris.go
deleted file mode 100644
index 3d86473..0000000
--- a/vendor/golang.org/x/sys/unix/mksyscall_solaris.go
+++ /dev/null
@@ -1,335 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-/*
- This program reads a file containing function prototypes
- (like syscall_solaris.go) and generates system call bodies.
- The prototypes are marked by lines beginning with "//sys"
- and read like func declarations if //sys is replaced by func, but:
- * The parameter lists must give a name for each argument.
- This includes return parameters.
- * The parameter lists must give a type for each argument:
- the (x, y, z int) shorthand is not allowed.
- * If the return parameter is an error number, it must be named err.
- * If go func name needs to be different than its libc name,
- * or the function is not in libc, name could be specified
- * at the end, after "=" sign, like
- //sys getsockopt(s int, level int, name int, val uintptr, vallen *_Socklen) (err error) = libsocket.getsockopt
-*/
-
-package main
-
-import (
- "bufio"
- "flag"
- "fmt"
- "os"
- "regexp"
- "strings"
-)
-
-var (
- b32 = flag.Bool("b32", false, "32bit big-endian")
- l32 = flag.Bool("l32", false, "32bit little-endian")
- tags = flag.String("tags", "", "build tags")
-)
-
-// cmdLine returns this programs's commandline arguments
-func cmdLine() string {
- return "go run mksyscall_solaris.go " + strings.Join(os.Args[1:], " ")
-}
-
-// buildTags returns build tags
-func buildTags() string {
- return *tags
-}
-
-// Param is function parameter
-type Param struct {
- Name string
- Type string
-}
-
-// usage prints the program usage
-func usage() {
- fmt.Fprintf(os.Stderr, "usage: go run mksyscall_solaris.go [-b32 | -l32] [-tags x,y] [file ...]\n")
- os.Exit(1)
-}
-
-// parseParamList parses parameter list and returns a slice of parameters
-func parseParamList(list string) []string {
- list = strings.TrimSpace(list)
- if list == "" {
- return []string{}
- }
- return regexp.MustCompile(`\s*,\s*`).Split(list, -1)
-}
-
-// parseParam splits a parameter into name and type
-func parseParam(p string) Param {
- ps := regexp.MustCompile(`^(\S*) (\S*)$`).FindStringSubmatch(p)
- if ps == nil {
- fmt.Fprintf(os.Stderr, "malformed parameter: %s\n", p)
- os.Exit(1)
- }
- return Param{ps[1], ps[2]}
-}
-
-func main() {
- flag.Usage = usage
- flag.Parse()
- if len(flag.Args()) <= 0 {
- fmt.Fprintf(os.Stderr, "no files to parse provided\n")
- usage()
- }
-
- endianness := ""
- if *b32 {
- endianness = "big-endian"
- } else if *l32 {
- endianness = "little-endian"
- }
-
- pack := ""
- text := ""
- dynimports := ""
- linknames := ""
- var vars []string
- for _, path := range flag.Args() {
- file, err := os.Open(path)
- if err != nil {
- fmt.Fprintf(os.Stderr, err.Error())
- os.Exit(1)
- }
- s := bufio.NewScanner(file)
- for s.Scan() {
- t := s.Text()
- t = strings.TrimSpace(t)
- t = regexp.MustCompile(`\s+`).ReplaceAllString(t, ` `)
- if p := regexp.MustCompile(`^package (\S+)$`).FindStringSubmatch(t); p != nil && pack == "" {
- pack = p[1]
- }
- nonblock := regexp.MustCompile(`^\/\/sysnb `).FindStringSubmatch(t)
- if regexp.MustCompile(`^\/\/sys `).FindStringSubmatch(t) == nil && nonblock == nil {
- continue
- }
-
- // Line must be of the form
- // func Open(path string, mode int, perm int) (fd int, err error)
- // Split into name, in params, out params.
- f := regexp.MustCompile(`^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*(?:(\w*)\.)?(\w*))?$`).FindStringSubmatch(t)
- if f == nil {
- fmt.Fprintf(os.Stderr, "%s:%s\nmalformed //sys declaration\n", path, t)
- os.Exit(1)
- }
- funct, inps, outps, modname, sysname := f[2], f[3], f[4], f[5], f[6]
-
- // Split argument lists on comma.
- in := parseParamList(inps)
- out := parseParamList(outps)
-
- inps = strings.Join(in, ", ")
- outps = strings.Join(out, ", ")
-
- // Try in vain to keep people from editing this file.
- // The theory is that they jump into the middle of the file
- // without reading the header.
- text += "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n"
-
- // So file name.
- if modname == "" {
- modname = "libc"
- }
-
- // System call name.
- if sysname == "" {
- sysname = funct
- }
-
- // System call pointer variable name.
- sysvarname := fmt.Sprintf("proc%s", sysname)
-
- strconvfunc := "BytePtrFromString"
- strconvtype := "*byte"
-
- sysname = strings.ToLower(sysname) // All libc functions are lowercase.
-
- // Runtime import of function to allow cross-platform builds.
- dynimports += fmt.Sprintf("//go:cgo_import_dynamic libc_%s %s \"%s.so\"\n", sysname, sysname, modname)
- // Link symbol to proc address variable.
- linknames += fmt.Sprintf("//go:linkname %s libc_%s\n", sysvarname, sysname)
- // Library proc address variable.
- vars = append(vars, sysvarname)
-
- // Go function header.
- outlist := strings.Join(out, ", ")
- if outlist != "" {
- outlist = fmt.Sprintf(" (%s)", outlist)
- }
- if text != "" {
- text += "\n"
- }
- text += fmt.Sprintf("func %s(%s)%s {\n", funct, strings.Join(in, ", "), outlist)
-
- // Check if err return available
- errvar := ""
- for _, param := range out {
- p := parseParam(param)
- if p.Type == "error" {
- errvar = p.Name
- continue
- }
- }
-
- // Prepare arguments to Syscall.
- var args []string
- n := 0
- for _, param := range in {
- p := parseParam(param)
- if regexp.MustCompile(`^\*`).FindStringSubmatch(p.Type) != nil {
- args = append(args, "uintptr(unsafe.Pointer("+p.Name+"))")
- } else if p.Type == "string" && errvar != "" {
- text += fmt.Sprintf("\tvar _p%d %s\n", n, strconvtype)
- text += fmt.Sprintf("\t_p%d, %s = %s(%s)\n", n, errvar, strconvfunc, p.Name)
- text += fmt.Sprintf("\tif %s != nil {\n\t\treturn\n\t}\n", errvar)
- args = append(args, fmt.Sprintf("uintptr(unsafe.Pointer(_p%d))", n))
- n++
- } else if p.Type == "string" {
- fmt.Fprintf(os.Stderr, path+":"+funct+" uses string arguments, but has no error return\n")
- text += fmt.Sprintf("\tvar _p%d %s\n", n, strconvtype)
- text += fmt.Sprintf("\t_p%d, _ = %s(%s)\n", n, strconvfunc, p.Name)
- args = append(args, fmt.Sprintf("uintptr(unsafe.Pointer(_p%d))", n))
- n++
- } else if s := regexp.MustCompile(`^\[\](.*)`).FindStringSubmatch(p.Type); s != nil {
- // Convert slice into pointer, length.
- // Have to be careful not to take address of &a[0] if len == 0:
- // pass nil in that case.
- text += fmt.Sprintf("\tvar _p%d *%s\n", n, s[1])
- text += fmt.Sprintf("\tif len(%s) > 0 {\n\t\t_p%d = &%s[0]\n\t}\n", p.Name, n, p.Name)
- args = append(args, fmt.Sprintf("uintptr(unsafe.Pointer(_p%d))", n), fmt.Sprintf("uintptr(len(%s))", p.Name))
- n++
- } else if p.Type == "int64" && endianness != "" {
- if endianness == "big-endian" {
- args = append(args, fmt.Sprintf("uintptr(%s>>32)", p.Name), fmt.Sprintf("uintptr(%s)", p.Name))
- } else {
- args = append(args, fmt.Sprintf("uintptr(%s)", p.Name), fmt.Sprintf("uintptr(%s>>32)", p.Name))
- }
- } else if p.Type == "bool" {
- text += fmt.Sprintf("\tvar _p%d uint32\n", n)
- text += fmt.Sprintf("\tif %s {\n\t\t_p%d = 1\n\t} else {\n\t\t_p%d = 0\n\t}\n", p.Name, n, n)
- args = append(args, fmt.Sprintf("uintptr(_p%d)", n))
- n++
- } else {
- args = append(args, fmt.Sprintf("uintptr(%s)", p.Name))
- }
- }
- nargs := len(args)
-
- // Determine which form to use; pad args with zeros.
- asm := "sysvicall6"
- if nonblock != nil {
- asm = "rawSysvicall6"
- }
- if len(args) <= 6 {
- for len(args) < 6 {
- args = append(args, "0")
- }
- } else {
- fmt.Fprintf(os.Stderr, "%s: too many arguments to system call\n", path)
- os.Exit(1)
- }
-
- // Actual call.
- arglist := strings.Join(args, ", ")
- call := fmt.Sprintf("%s(uintptr(unsafe.Pointer(&%s)), %d, %s)", asm, sysvarname, nargs, arglist)
-
- // Assign return values.
- body := ""
- ret := []string{"_", "_", "_"}
- doErrno := false
- for i := 0; i < len(out); i++ {
- p := parseParam(out[i])
- reg := ""
- if p.Name == "err" {
- reg = "e1"
- ret[2] = reg
- doErrno = true
- } else {
- reg = fmt.Sprintf("r%d", i)
- ret[i] = reg
- }
- if p.Type == "bool" {
- reg = fmt.Sprintf("%d != 0", reg)
- }
- if p.Type == "int64" && endianness != "" {
- // 64-bit number in r1:r0 or r0:r1.
- if i+2 > len(out) {
- fmt.Fprintf(os.Stderr, "%s: not enough registers for int64 return\n", path)
- os.Exit(1)
- }
- if endianness == "big-endian" {
- reg = fmt.Sprintf("int64(r%d)<<32 | int64(r%d)", i, i+1)
- } else {
- reg = fmt.Sprintf("int64(r%d)<<32 | int64(r%d)", i+1, i)
- }
- ret[i] = fmt.Sprintf("r%d", i)
- ret[i+1] = fmt.Sprintf("r%d", i+1)
- }
- if reg != "e1" {
- body += fmt.Sprintf("\t%s = %s(%s)\n", p.Name, p.Type, reg)
- }
- }
- if ret[0] == "_" && ret[1] == "_" && ret[2] == "_" {
- text += fmt.Sprintf("\t%s\n", call)
- } else {
- text += fmt.Sprintf("\t%s, %s, %s := %s\n", ret[0], ret[1], ret[2], call)
- }
- text += body
-
- if doErrno {
- text += "\tif e1 != 0 {\n"
- text += "\t\terr = e1\n"
- text += "\t}\n"
- }
- text += "\treturn\n"
- text += "}\n"
- }
- if err := s.Err(); err != nil {
- fmt.Fprintf(os.Stderr, err.Error())
- os.Exit(1)
- }
- file.Close()
- }
- imp := ""
- if pack != "unix" {
- imp = "import \"golang.org/x/sys/unix\"\n"
-
- }
- vardecls := "\t" + strings.Join(vars, ",\n\t")
- vardecls += " syscallFunc"
- fmt.Printf(srcTemplate, cmdLine(), buildTags(), pack, imp, dynimports, linknames, vardecls, text)
-}
-
-const srcTemplate = `// %s
-// Code generated by the command above; see README.md. DO NOT EDIT.
-
-// +build %s
-
-package %s
-
-import (
- "syscall"
- "unsafe"
-)
-%s
-%s
-%s
-var (
-%s
-)
-
-%s
-`
diff --git a/vendor/golang.org/x/sys/unix/mksysnum.go b/vendor/golang.org/x/sys/unix/mksysnum.go
deleted file mode 100644
index 07f8960..0000000
--- a/vendor/golang.org/x/sys/unix/mksysnum.go
+++ /dev/null
@@ -1,190 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-// Generate system call table for DragonFly, NetBSD,
-// FreeBSD, OpenBSD or Darwin from master list
-// (for example, /usr/src/sys/kern/syscalls.master or
-// sys/syscall.h).
-package main
-
-import (
- "bufio"
- "fmt"
- "io"
- "io/ioutil"
- "net/http"
- "os"
- "regexp"
- "strings"
-)
-
-var (
- goos, goarch string
-)
-
-// cmdLine returns this programs's commandline arguments
-func cmdLine() string {
- return "go run mksysnum.go " + strings.Join(os.Args[1:], " ")
-}
-
-// buildTags returns build tags
-func buildTags() string {
- return fmt.Sprintf("%s,%s", goarch, goos)
-}
-
-func checkErr(err error) {
- if err != nil {
- fmt.Fprintf(os.Stderr, "%v\n", err)
- os.Exit(1)
- }
-}
-
-// source string and substring slice for regexp
-type re struct {
- str string // source string
- sub []string // matched sub-string
-}
-
-// Match performs regular expression match
-func (r *re) Match(exp string) bool {
- r.sub = regexp.MustCompile(exp).FindStringSubmatch(r.str)
- if r.sub != nil {
- return true
- }
- return false
-}
-
-// fetchFile fetches a text file from URL
-func fetchFile(URL string) io.Reader {
- resp, err := http.Get(URL)
- checkErr(err)
- defer resp.Body.Close()
- body, err := ioutil.ReadAll(resp.Body)
- checkErr(err)
- return strings.NewReader(string(body))
-}
-
-// readFile reads a text file from path
-func readFile(path string) io.Reader {
- file, err := os.Open(os.Args[1])
- checkErr(err)
- return file
-}
-
-func format(name, num, proto string) string {
- name = strings.ToUpper(name)
- // There are multiple entries for enosys and nosys, so comment them out.
- nm := re{str: name}
- if nm.Match(`^SYS_E?NOSYS$`) {
- name = fmt.Sprintf("// %s", name)
- }
- if name == `SYS_SYS_EXIT` {
- name = `SYS_EXIT`
- }
- return fmt.Sprintf(" %s = %s; // %s\n", name, num, proto)
-}
-
-func main() {
- // Get the OS (using GOOS_TARGET if it exist)
- goos = os.Getenv("GOOS_TARGET")
- if goos == "" {
- goos = os.Getenv("GOOS")
- }
- // Get the architecture (using GOARCH_TARGET if it exists)
- goarch = os.Getenv("GOARCH_TARGET")
- if goarch == "" {
- goarch = os.Getenv("GOARCH")
- }
- // Check if GOOS and GOARCH environment variables are defined
- if goarch == "" || goos == "" {
- fmt.Fprintf(os.Stderr, "GOARCH or GOOS not defined in environment\n")
- os.Exit(1)
- }
-
- file := strings.TrimSpace(os.Args[1])
- var syscalls io.Reader
- if strings.HasPrefix(file, "https://") || strings.HasPrefix(file, "http://") {
- // Download syscalls.master file
- syscalls = fetchFile(file)
- } else {
- syscalls = readFile(file)
- }
-
- var text, line string
- s := bufio.NewScanner(syscalls)
- for s.Scan() {
- t := re{str: line}
- if t.Match(`^(.*)\\$`) {
- // Handle continuation
- line = t.sub[1]
- line += strings.TrimLeft(s.Text(), " \t")
- } else {
- // New line
- line = s.Text()
- }
- t = re{str: line}
- if t.Match(`\\$`) {
- continue
- }
- t = re{str: line}
-
- switch goos {
- case "dragonfly":
- if t.Match(`^([0-9]+)\s+STD\s+({ \S+\s+(\w+).*)$`) {
- num, proto := t.sub[1], t.sub[2]
- name := fmt.Sprintf("SYS_%s", t.sub[3])
- text += format(name, num, proto)
- }
- case "freebsd":
- if t.Match(`^([0-9]+)\s+\S+\s+(?:NO)?STD\s+({ \S+\s+(\w+).*)$`) {
- num, proto := t.sub[1], t.sub[2]
- name := fmt.Sprintf("SYS_%s", t.sub[3])
- text += format(name, num, proto)
- }
- case "openbsd":
- if t.Match(`^([0-9]+)\s+STD\s+(NOLOCK\s+)?({ \S+\s+\*?(\w+).*)$`) {
- num, proto, name := t.sub[1], t.sub[3], t.sub[4]
- text += format(name, num, proto)
- }
- case "netbsd":
- if t.Match(`^([0-9]+)\s+((STD)|(NOERR))\s+(RUMP\s+)?({\s+\S+\s*\*?\s*\|(\S+)\|(\S*)\|(\w+).*\s+})(\s+(\S+))?$`) {
- num, proto, compat := t.sub[1], t.sub[6], t.sub[8]
- name := t.sub[7] + "_" + t.sub[9]
- if t.sub[11] != "" {
- name = t.sub[7] + "_" + t.sub[11]
- }
- name = strings.ToUpper(name)
- if compat == "" || compat == "13" || compat == "30" || compat == "50" {
- text += fmt.Sprintf(" %s = %s; // %s\n", name, num, proto)
- }
- }
- case "darwin":
- if t.Match(`^#define\s+SYS_(\w+)\s+([0-9]+)`) {
- name, num := t.sub[1], t.sub[2]
- name = strings.ToUpper(name)
- text += fmt.Sprintf(" SYS_%s = %s;\n", name, num)
- }
- default:
- fmt.Fprintf(os.Stderr, "unrecognized GOOS=%s\n", goos)
- os.Exit(1)
-
- }
- }
- err := s.Err()
- checkErr(err)
-
- fmt.Printf(template, cmdLine(), buildTags(), text)
-}
-
-const template = `// %s
-// Code generated by the command above; see README.md. DO NOT EDIT.
-
-// +build %s
-
-package unix
-
-const(
-%s)`
diff --git a/vendor/golang.org/x/sys/unix/types_aix.go b/vendor/golang.org/x/sys/unix/types_aix.go
deleted file mode 100644
index 25e8349..0000000
--- a/vendor/golang.org/x/sys/unix/types_aix.go
+++ /dev/null
@@ -1,236 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-// +build aix
-
-/*
-Input to cgo -godefs. See also mkerrors.sh and mkall.sh
-*/
-
-// +godefs map struct_in_addr [4]byte /* in_addr */
-// +godefs map struct_in6_addr [16]byte /* in6_addr */
-
-package unix
-
-/*
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/limits.h>
-#include <sys/un.h>
-#include <utime.h>
-#include <sys/utsname.h>
-#include <sys/poll.h>
-#include <sys/resource.h>
-#include <sys/stat.h>
-#include <sys/statfs.h>
-#include <sys/termio.h>
-#include <sys/ioctl.h>
-
-#include <termios.h>
-
-#include <net/if.h>
-#include <net/if_dl.h>
-#include <netinet/in.h>
-#include <netinet/icmp6.h>
-
-
-#include <dirent.h>
-#include <fcntl.h>
-
-enum {
- sizeofPtr = sizeof(void*),
-};
-
-union sockaddr_all {
- struct sockaddr s1; // this one gets used for fields
- struct sockaddr_in s2; // these pad it out
- struct sockaddr_in6 s3;
- struct sockaddr_un s4;
- struct sockaddr_dl s5;
-};
-
-struct sockaddr_any {
- struct sockaddr addr;
- char pad[sizeof(union sockaddr_all) - sizeof(struct sockaddr)];
-};
-
-*/
-import "C"
-
-// Machine characteristics
-
-const (
- SizeofPtr = C.sizeofPtr
- SizeofShort = C.sizeof_short
- SizeofInt = C.sizeof_int
- SizeofLong = C.sizeof_long
- SizeofLongLong = C.sizeof_longlong
- PathMax = C.PATH_MAX
-)
-
-// Basic types
-
-type (
- _C_short C.short
- _C_int C.int
- _C_long C.long
- _C_long_long C.longlong
-)
-
-type off64 C.off64_t
-type off C.off_t
-type Mode_t C.mode_t
-
-// Time
-
-type Timespec C.struct_timespec
-
-type StTimespec C.struct_st_timespec
-
-type Timeval C.struct_timeval
-
-type Timeval32 C.struct_timeval32
-
-type Timex C.struct_timex
-
-type Time_t C.time_t
-
-type Tms C.struct_tms
-
-type Utimbuf C.struct_utimbuf
-
-type Timezone C.struct_timezone
-
-// Processes
-
-type Rusage C.struct_rusage
-
-type Rlimit C.struct_rlimit64
-
-type Pid_t C.pid_t
-
-type _Gid_t C.gid_t
-
-type dev_t C.dev_t
-
-// Files
-
-type Stat_t C.struct_stat
-
-type StatxTimestamp C.struct_statx_timestamp
-
-type Statx_t C.struct_statx
-
-type Dirent C.struct_dirent
-
-// Sockets
-
-type RawSockaddrInet4 C.struct_sockaddr_in
-
-type RawSockaddrInet6 C.struct_sockaddr_in6
-
-type RawSockaddrUnix C.struct_sockaddr_un
-
-type RawSockaddr C.struct_sockaddr
-
-type RawSockaddrAny C.struct_sockaddr_any
-
-type _Socklen C.socklen_t
-
-type Cmsghdr C.struct_cmsghdr
-
-type ICMPv6Filter C.struct_icmp6_filter
-
-type Iovec C.struct_iovec
-
-type IPMreq C.struct_ip_mreq
-
-type IPv6Mreq C.struct_ipv6_mreq
-
-type IPv6MTUInfo C.struct_ip6_mtuinfo
-
-type Linger C.struct_linger
-
-type Msghdr C.struct_msghdr
-
-const (
- SizeofSockaddrInet4 = C.sizeof_struct_sockaddr_in
- SizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6
- SizeofSockaddrAny = C.sizeof_struct_sockaddr_any
- SizeofSockaddrUnix = C.sizeof_struct_sockaddr_un
- SizeofLinger = C.sizeof_struct_linger
- SizeofIPMreq = C.sizeof_struct_ip_mreq
- SizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq
- SizeofIPv6MTUInfo = C.sizeof_struct_ip6_mtuinfo
- SizeofMsghdr = C.sizeof_struct_msghdr
- SizeofCmsghdr = C.sizeof_struct_cmsghdr
- SizeofICMPv6Filter = C.sizeof_struct_icmp6_filter
-)
-
-// Routing and interface messages
-
-const (
- SizeofIfMsghdr = C.sizeof_struct_if_msghdr
-)
-
-type IfMsgHdr C.struct_if_msghdr
-
-// Misc
-
-type FdSet C.fd_set
-
-type Utsname C.struct_utsname
-
-type Ustat_t C.struct_ustat
-
-type Sigset_t C.sigset_t
-
-const (
- AT_FDCWD = C.AT_FDCWD
- AT_REMOVEDIR = C.AT_REMOVEDIR
- AT_SYMLINK_NOFOLLOW = C.AT_SYMLINK_NOFOLLOW
-)
-
-// Terminal handling
-
-type Termios C.struct_termios
-
-type Termio C.struct_termio
-
-type Winsize C.struct_winsize
-
-//poll
-
-type PollFd struct {
- Fd int32
- Events uint16
- Revents uint16
-}
-
-const (
- POLLERR = C.POLLERR
- POLLHUP = C.POLLHUP
- POLLIN = C.POLLIN
- POLLNVAL = C.POLLNVAL
- POLLOUT = C.POLLOUT
- POLLPRI = C.POLLPRI
- POLLRDBAND = C.POLLRDBAND
- POLLRDNORM = C.POLLRDNORM
- POLLWRBAND = C.POLLWRBAND
- POLLWRNORM = C.POLLWRNORM
-)
-
-//flock_t
-
-type Flock_t C.struct_flock64
-
-// Statfs
-
-type Fsid_t C.struct_fsid_t
-type Fsid64_t C.struct_fsid64_t
-
-type Statfs_t C.struct_statfs
-
-const RNDGETENTCNT = 0x80045200
diff --git a/vendor/golang.org/x/sys/unix/types_darwin.go b/vendor/golang.org/x/sys/unix/types_darwin.go
deleted file mode 100644
index 155c2e6..0000000
--- a/vendor/golang.org/x/sys/unix/types_darwin.go
+++ /dev/null
@@ -1,283 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-/*
-Input to cgo -godefs. See README.md
-*/
-
-// +godefs map struct_in_addr [4]byte /* in_addr */
-// +godefs map struct_in6_addr [16]byte /* in6_addr */
-
-package unix
-
-/*
-#define __DARWIN_UNIX03 0
-#define KERNEL
-#define _DARWIN_USE_64_BIT_INODE
-#include <dirent.h>
-#include <fcntl.h>
-#include <poll.h>
-#include <signal.h>
-#include <termios.h>
-#include <unistd.h>
-#include <mach/mach.h>
-#include <mach/message.h>
-#include <sys/event.h>
-#include <sys/mman.h>
-#include <sys/mount.h>
-#include <sys/param.h>
-#include <sys/ptrace.h>
-#include <sys/resource.h>
-#include <sys/select.h>
-#include <sys/signal.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <sys/un.h>
-#include <sys/utsname.h>
-#include <sys/wait.h>
-#include <net/bpf.h>
-#include <net/if.h>
-#include <net/if_dl.h>
-#include <net/if_var.h>
-#include <net/route.h>
-#include <netinet/in.h>
-#include <netinet/icmp6.h>
-#include <netinet/tcp.h>
-
-enum {
- sizeofPtr = sizeof(void*),
-};
-
-union sockaddr_all {
- struct sockaddr s1; // this one gets used for fields
- struct sockaddr_in s2; // these pad it out
- struct sockaddr_in6 s3;
- struct sockaddr_un s4;
- struct sockaddr_dl s5;
-};
-
-struct sockaddr_any {
- struct sockaddr addr;
- char pad[sizeof(union sockaddr_all) - sizeof(struct sockaddr)];
-};
-
-*/
-import "C"
-
-// Machine characteristics
-
-const (
- SizeofPtr = C.sizeofPtr
- SizeofShort = C.sizeof_short
- SizeofInt = C.sizeof_int
- SizeofLong = C.sizeof_long
- SizeofLongLong = C.sizeof_longlong
-)
-
-// Basic types
-
-type (
- _C_short C.short
- _C_int C.int
- _C_long C.long
- _C_long_long C.longlong
-)
-
-// Time
-
-type Timespec C.struct_timespec
-
-type Timeval C.struct_timeval
-
-type Timeval32 C.struct_timeval32
-
-// Processes
-
-type Rusage C.struct_rusage
-
-type Rlimit C.struct_rlimit
-
-type _Gid_t C.gid_t
-
-// Files
-
-type Stat_t C.struct_stat64
-
-type Statfs_t C.struct_statfs64
-
-type Flock_t C.struct_flock
-
-type Fstore_t C.struct_fstore
-
-type Radvisory_t C.struct_radvisory
-
-type Fbootstraptransfer_t C.struct_fbootstraptransfer
-
-type Log2phys_t C.struct_log2phys
-
-type Fsid C.struct_fsid
-
-type Dirent C.struct_dirent
-
-// Sockets
-
-type RawSockaddrInet4 C.struct_sockaddr_in
-
-type RawSockaddrInet6 C.struct_sockaddr_in6
-
-type RawSockaddrUnix C.struct_sockaddr_un
-
-type RawSockaddrDatalink C.struct_sockaddr_dl
-
-type RawSockaddr C.struct_sockaddr
-
-type RawSockaddrAny C.struct_sockaddr_any
-
-type _Socklen C.socklen_t
-
-type Linger C.struct_linger
-
-type Iovec C.struct_iovec
-
-type IPMreq C.struct_ip_mreq
-
-type IPv6Mreq C.struct_ipv6_mreq
-
-type Msghdr C.struct_msghdr
-
-type Cmsghdr C.struct_cmsghdr
-
-type Inet4Pktinfo C.struct_in_pktinfo
-
-type Inet6Pktinfo C.struct_in6_pktinfo
-
-type IPv6MTUInfo C.struct_ip6_mtuinfo
-
-type ICMPv6Filter C.struct_icmp6_filter
-
-const (
- SizeofSockaddrInet4 = C.sizeof_struct_sockaddr_in
- SizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6
- SizeofSockaddrAny = C.sizeof_struct_sockaddr_any
- SizeofSockaddrUnix = C.sizeof_struct_sockaddr_un
- SizeofSockaddrDatalink = C.sizeof_struct_sockaddr_dl
- SizeofLinger = C.sizeof_struct_linger
- SizeofIPMreq = C.sizeof_struct_ip_mreq
- SizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq
- SizeofMsghdr = C.sizeof_struct_msghdr
- SizeofCmsghdr = C.sizeof_struct_cmsghdr
- SizeofInet4Pktinfo = C.sizeof_struct_in_pktinfo
- SizeofInet6Pktinfo = C.sizeof_struct_in6_pktinfo
- SizeofIPv6MTUInfo = C.sizeof_struct_ip6_mtuinfo
- SizeofICMPv6Filter = C.sizeof_struct_icmp6_filter
-)
-
-// Ptrace requests
-
-const (
- PTRACE_TRACEME = C.PT_TRACE_ME
- PTRACE_CONT = C.PT_CONTINUE
- PTRACE_KILL = C.PT_KILL
-)
-
-// Events (kqueue, kevent)
-
-type Kevent_t C.struct_kevent
-
-// Select
-
-type FdSet C.fd_set
-
-// Routing and interface messages
-
-const (
- SizeofIfMsghdr = C.sizeof_struct_if_msghdr
- SizeofIfData = C.sizeof_struct_if_data
- SizeofIfaMsghdr = C.sizeof_struct_ifa_msghdr
- SizeofIfmaMsghdr = C.sizeof_struct_ifma_msghdr
- SizeofIfmaMsghdr2 = C.sizeof_struct_ifma_msghdr2
- SizeofRtMsghdr = C.sizeof_struct_rt_msghdr
- SizeofRtMetrics = C.sizeof_struct_rt_metrics
-)
-
-type IfMsghdr C.struct_if_msghdr
-
-type IfData C.struct_if_data
-
-type IfaMsghdr C.struct_ifa_msghdr
-
-type IfmaMsghdr C.struct_ifma_msghdr
-
-type IfmaMsghdr2 C.struct_ifma_msghdr2
-
-type RtMsghdr C.struct_rt_msghdr
-
-type RtMetrics C.struct_rt_metrics
-
-// Berkeley packet filter
-
-const (
- SizeofBpfVersion = C.sizeof_struct_bpf_version
- SizeofBpfStat = C.sizeof_struct_bpf_stat
- SizeofBpfProgram = C.sizeof_struct_bpf_program
- SizeofBpfInsn = C.sizeof_struct_bpf_insn
- SizeofBpfHdr = C.sizeof_struct_bpf_hdr
-)
-
-type BpfVersion C.struct_bpf_version
-
-type BpfStat C.struct_bpf_stat
-
-type BpfProgram C.struct_bpf_program
-
-type BpfInsn C.struct_bpf_insn
-
-type BpfHdr C.struct_bpf_hdr
-
-// Terminal handling
-
-type Termios C.struct_termios
-
-type Winsize C.struct_winsize
-
-// fchmodat-like syscalls.
-
-const (
- AT_FDCWD = C.AT_FDCWD
- AT_REMOVEDIR = C.AT_REMOVEDIR
- AT_SYMLINK_FOLLOW = C.AT_SYMLINK_FOLLOW
- AT_SYMLINK_NOFOLLOW = C.AT_SYMLINK_NOFOLLOW
-)
-
-// poll
-
-type PollFd C.struct_pollfd
-
-const (
- POLLERR = C.POLLERR
- POLLHUP = C.POLLHUP
- POLLIN = C.POLLIN
- POLLNVAL = C.POLLNVAL
- POLLOUT = C.POLLOUT
- POLLPRI = C.POLLPRI
- POLLRDBAND = C.POLLRDBAND
- POLLRDNORM = C.POLLRDNORM
- POLLWRBAND = C.POLLWRBAND
- POLLWRNORM = C.POLLWRNORM
-)
-
-// uname
-
-type Utsname C.struct_utsname
-
-// Clockinfo
-
-const SizeofClockinfo = C.sizeof_struct_clockinfo
-
-type Clockinfo C.struct_clockinfo
diff --git a/vendor/golang.org/x/sys/unix/types_dragonfly.go b/vendor/golang.org/x/sys/unix/types_dragonfly.go
deleted file mode 100644
index 3365dd7..0000000
--- a/vendor/golang.org/x/sys/unix/types_dragonfly.go
+++ /dev/null
@@ -1,263 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-/*
-Input to cgo -godefs. See README.md
-*/
-
-// +godefs map struct_in_addr [4]byte /* in_addr */
-// +godefs map struct_in6_addr [16]byte /* in6_addr */
-
-package unix
-
-/*
-#define KERNEL
-#include <dirent.h>
-#include <fcntl.h>
-#include <poll.h>
-#include <signal.h>
-#include <termios.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/event.h>
-#include <sys/mman.h>
-#include <sys/mount.h>
-#include <sys/param.h>
-#include <sys/ptrace.h>
-#include <sys/resource.h>
-#include <sys/select.h>
-#include <sys/signal.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/un.h>
-#include <sys/utsname.h>
-#include <sys/wait.h>
-#include <net/bpf.h>
-#include <net/if.h>
-#include <net/if_dl.h>
-#include <net/route.h>
-#include <netinet/in.h>
-#include <netinet/icmp6.h>
-#include <netinet/tcp.h>
-
-enum {
- sizeofPtr = sizeof(void*),
-};
-
-union sockaddr_all {
- struct sockaddr s1; // this one gets used for fields
- struct sockaddr_in s2; // these pad it out
- struct sockaddr_in6 s3;
- struct sockaddr_un s4;
- struct sockaddr_dl s5;
-};
-
-struct sockaddr_any {
- struct sockaddr addr;
- char pad[sizeof(union sockaddr_all) - sizeof(struct sockaddr)];
-};
-
-*/
-import "C"
-
-// Machine characteristics
-
-const (
- SizeofPtr = C.sizeofPtr
- SizeofShort = C.sizeof_short
- SizeofInt = C.sizeof_int
- SizeofLong = C.sizeof_long
- SizeofLongLong = C.sizeof_longlong
-)
-
-// Basic types
-
-type (
- _C_short C.short
- _C_int C.int
- _C_long C.long
- _C_long_long C.longlong
-)
-
-// Time
-
-type Timespec C.struct_timespec
-
-type Timeval C.struct_timeval
-
-// Processes
-
-type Rusage C.struct_rusage
-
-type Rlimit C.struct_rlimit
-
-type _Gid_t C.gid_t
-
-// Files
-
-type Stat_t C.struct_stat
-
-type Statfs_t C.struct_statfs
-
-type Flock_t C.struct_flock
-
-type Dirent C.struct_dirent
-
-type Fsid C.struct_fsid
-
-// File system limits
-
-const (
- PathMax = C.PATH_MAX
-)
-
-// Sockets
-
-type RawSockaddrInet4 C.struct_sockaddr_in
-
-type RawSockaddrInet6 C.struct_sockaddr_in6
-
-type RawSockaddrUnix C.struct_sockaddr_un
-
-type RawSockaddrDatalink C.struct_sockaddr_dl
-
-type RawSockaddr C.struct_sockaddr
-
-type RawSockaddrAny C.struct_sockaddr_any
-
-type _Socklen C.socklen_t
-
-type Linger C.struct_linger
-
-type Iovec C.struct_iovec
-
-type IPMreq C.struct_ip_mreq
-
-type IPv6Mreq C.struct_ipv6_mreq
-
-type Msghdr C.struct_msghdr
-
-type Cmsghdr C.struct_cmsghdr
-
-type Inet6Pktinfo C.struct_in6_pktinfo
-
-type IPv6MTUInfo C.struct_ip6_mtuinfo
-
-type ICMPv6Filter C.struct_icmp6_filter
-
-const (
- SizeofSockaddrInet4 = C.sizeof_struct_sockaddr_in
- SizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6
- SizeofSockaddrAny = C.sizeof_struct_sockaddr_any
- SizeofSockaddrUnix = C.sizeof_struct_sockaddr_un
- SizeofSockaddrDatalink = C.sizeof_struct_sockaddr_dl
- SizeofLinger = C.sizeof_struct_linger
- SizeofIPMreq = C.sizeof_struct_ip_mreq
- SizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq
- SizeofMsghdr = C.sizeof_struct_msghdr
- SizeofCmsghdr = C.sizeof_struct_cmsghdr
- SizeofInet6Pktinfo = C.sizeof_struct_in6_pktinfo
- SizeofIPv6MTUInfo = C.sizeof_struct_ip6_mtuinfo
- SizeofICMPv6Filter = C.sizeof_struct_icmp6_filter
-)
-
-// Ptrace requests
-
-const (
- PTRACE_TRACEME = C.PT_TRACE_ME
- PTRACE_CONT = C.PT_CONTINUE
- PTRACE_KILL = C.PT_KILL
-)
-
-// Events (kqueue, kevent)
-
-type Kevent_t C.struct_kevent
-
-// Select
-
-type FdSet C.fd_set
-
-// Routing and interface messages
-
-const (
- SizeofIfMsghdr = C.sizeof_struct_if_msghdr
- SizeofIfData = C.sizeof_struct_if_data
- SizeofIfaMsghdr = C.sizeof_struct_ifa_msghdr
- SizeofIfmaMsghdr = C.sizeof_struct_ifma_msghdr
- SizeofIfAnnounceMsghdr = C.sizeof_struct_if_announcemsghdr
- SizeofRtMsghdr = C.sizeof_struct_rt_msghdr
- SizeofRtMetrics = C.sizeof_struct_rt_metrics
-)
-
-type IfMsghdr C.struct_if_msghdr
-
-type IfData C.struct_if_data
-
-type IfaMsghdr C.struct_ifa_msghdr
-
-type IfmaMsghdr C.struct_ifma_msghdr
-
-type IfAnnounceMsghdr C.struct_if_announcemsghdr
-
-type RtMsghdr C.struct_rt_msghdr
-
-type RtMetrics C.struct_rt_metrics
-
-// Berkeley packet filter
-
-const (
- SizeofBpfVersion = C.sizeof_struct_bpf_version
- SizeofBpfStat = C.sizeof_struct_bpf_stat
- SizeofBpfProgram = C.sizeof_struct_bpf_program
- SizeofBpfInsn = C.sizeof_struct_bpf_insn
- SizeofBpfHdr = C.sizeof_struct_bpf_hdr
-)
-
-type BpfVersion C.struct_bpf_version
-
-type BpfStat C.struct_bpf_stat
-
-type BpfProgram C.struct_bpf_program
-
-type BpfInsn C.struct_bpf_insn
-
-type BpfHdr C.struct_bpf_hdr
-
-// Terminal handling
-
-type Termios C.struct_termios
-
-type Winsize C.struct_winsize
-
-// fchmodat-like syscalls.
-
-const (
- AT_FDCWD = C.AT_FDCWD
- AT_SYMLINK_NOFOLLOW = C.AT_SYMLINK_NOFOLLOW
-)
-
-// poll
-
-type PollFd C.struct_pollfd
-
-const (
- POLLERR = C.POLLERR
- POLLHUP = C.POLLHUP
- POLLIN = C.POLLIN
- POLLNVAL = C.POLLNVAL
- POLLOUT = C.POLLOUT
- POLLPRI = C.POLLPRI
- POLLRDBAND = C.POLLRDBAND
- POLLRDNORM = C.POLLRDNORM
- POLLWRBAND = C.POLLWRBAND
- POLLWRNORM = C.POLLWRNORM
-)
-
-// Uname
-
-type Utsname C.struct_utsname
diff --git a/vendor/golang.org/x/sys/unix/types_freebsd.go b/vendor/golang.org/x/sys/unix/types_freebsd.go
deleted file mode 100644
index 7470798..0000000
--- a/vendor/golang.org/x/sys/unix/types_freebsd.go
+++ /dev/null
@@ -1,356 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-/*
-Input to cgo -godefs. See README.md
-*/
-
-// +godefs map struct_in_addr [4]byte /* in_addr */
-// +godefs map struct_in6_addr [16]byte /* in6_addr */
-
-package unix
-
-/*
-#define _WANT_FREEBSD11_STAT 1
-#define _WANT_FREEBSD11_STATFS 1
-#define _WANT_FREEBSD11_DIRENT 1
-#define _WANT_FREEBSD11_KEVENT 1
-
-#include <dirent.h>
-#include <fcntl.h>
-#include <poll.h>
-#include <signal.h>
-#include <termios.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/capsicum.h>
-#include <sys/event.h>
-#include <sys/mman.h>
-#include <sys/mount.h>
-#include <sys/param.h>
-#include <sys/ptrace.h>
-#include <sys/resource.h>
-#include <sys/select.h>
-#include <sys/signal.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/un.h>
-#include <sys/utsname.h>
-#include <sys/wait.h>
-#include <net/bpf.h>
-#include <net/if.h>
-#include <net/if_dl.h>
-#include <net/route.h>
-#include <netinet/in.h>
-#include <netinet/icmp6.h>
-#include <netinet/tcp.h>
-
-enum {
- sizeofPtr = sizeof(void*),
-};
-
-union sockaddr_all {
- struct sockaddr s1; // this one gets used for fields
- struct sockaddr_in s2; // these pad it out
- struct sockaddr_in6 s3;
- struct sockaddr_un s4;
- struct sockaddr_dl s5;
-};
-
-struct sockaddr_any {
- struct sockaddr addr;
- char pad[sizeof(union sockaddr_all) - sizeof(struct sockaddr)];
-};
-
-// This structure is a duplicate of if_data on FreeBSD 8-STABLE.
-// See /usr/include/net/if.h.
-struct if_data8 {
- u_char ifi_type;
- u_char ifi_physical;
- u_char ifi_addrlen;
- u_char ifi_hdrlen;
- u_char ifi_link_state;
- u_char ifi_spare_char1;
- u_char ifi_spare_char2;
- u_char ifi_datalen;
- u_long ifi_mtu;
- u_long ifi_metric;
- u_long ifi_baudrate;
- u_long ifi_ipackets;
- u_long ifi_ierrors;
- u_long ifi_opackets;
- u_long ifi_oerrors;
- u_long ifi_collisions;
- u_long ifi_ibytes;
- u_long ifi_obytes;
- u_long ifi_imcasts;
- u_long ifi_omcasts;
- u_long ifi_iqdrops;
- u_long ifi_noproto;
- u_long ifi_hwassist;
-// FIXME: these are now unions, so maybe need to change definitions?
-#undef ifi_epoch
- time_t ifi_epoch;
-#undef ifi_lastchange
- struct timeval ifi_lastchange;
-};
-
-// This structure is a duplicate of if_msghdr on FreeBSD 8-STABLE.
-// See /usr/include/net/if.h.
-struct if_msghdr8 {
- u_short ifm_msglen;
- u_char ifm_version;
- u_char ifm_type;
- int ifm_addrs;
- int ifm_flags;
- u_short ifm_index;
- struct if_data8 ifm_data;
-};
-*/
-import "C"
-
-// Machine characteristics
-
-const (
- SizeofPtr = C.sizeofPtr
- SizeofShort = C.sizeof_short
- SizeofInt = C.sizeof_int
- SizeofLong = C.sizeof_long
- SizeofLongLong = C.sizeof_longlong
-)
-
-// Basic types
-
-type (
- _C_short C.short
- _C_int C.int
- _C_long C.long
- _C_long_long C.longlong
-)
-
-// Time
-
-type Timespec C.struct_timespec
-
-type Timeval C.struct_timeval
-
-// Processes
-
-type Rusage C.struct_rusage
-
-type Rlimit C.struct_rlimit
-
-type _Gid_t C.gid_t
-
-// Files
-
-const (
- _statfsVersion = C.STATFS_VERSION
- _dirblksiz = C.DIRBLKSIZ
-)
-
-type Stat_t C.struct_stat
-
-type stat_freebsd11_t C.struct_freebsd11_stat
-
-type Statfs_t C.struct_statfs
-
-type statfs_freebsd11_t C.struct_freebsd11_statfs
-
-type Flock_t C.struct_flock
-
-type Dirent C.struct_dirent
-
-type dirent_freebsd11 C.struct_freebsd11_dirent
-
-type Fsid C.struct_fsid
-
-// File system limits
-
-const (
- PathMax = C.PATH_MAX
-)
-
-// Advice to Fadvise
-
-const (
- FADV_NORMAL = C.POSIX_FADV_NORMAL
- FADV_RANDOM = C.POSIX_FADV_RANDOM
- FADV_SEQUENTIAL = C.POSIX_FADV_SEQUENTIAL
- FADV_WILLNEED = C.POSIX_FADV_WILLNEED
- FADV_DONTNEED = C.POSIX_FADV_DONTNEED
- FADV_NOREUSE = C.POSIX_FADV_NOREUSE
-)
-
-// Sockets
-
-type RawSockaddrInet4 C.struct_sockaddr_in
-
-type RawSockaddrInet6 C.struct_sockaddr_in6
-
-type RawSockaddrUnix C.struct_sockaddr_un
-
-type RawSockaddrDatalink C.struct_sockaddr_dl
-
-type RawSockaddr C.struct_sockaddr
-
-type RawSockaddrAny C.struct_sockaddr_any
-
-type _Socklen C.socklen_t
-
-type Linger C.struct_linger
-
-type Iovec C.struct_iovec
-
-type IPMreq C.struct_ip_mreq
-
-type IPMreqn C.struct_ip_mreqn
-
-type IPv6Mreq C.struct_ipv6_mreq
-
-type Msghdr C.struct_msghdr
-
-type Cmsghdr C.struct_cmsghdr
-
-type Inet6Pktinfo C.struct_in6_pktinfo
-
-type IPv6MTUInfo C.struct_ip6_mtuinfo
-
-type ICMPv6Filter C.struct_icmp6_filter
-
-const (
- SizeofSockaddrInet4 = C.sizeof_struct_sockaddr_in
- SizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6
- SizeofSockaddrAny = C.sizeof_struct_sockaddr_any
- SizeofSockaddrUnix = C.sizeof_struct_sockaddr_un
- SizeofSockaddrDatalink = C.sizeof_struct_sockaddr_dl
- SizeofLinger = C.sizeof_struct_linger
- SizeofIPMreq = C.sizeof_struct_ip_mreq
- SizeofIPMreqn = C.sizeof_struct_ip_mreqn
- SizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq
- SizeofMsghdr = C.sizeof_struct_msghdr
- SizeofCmsghdr = C.sizeof_struct_cmsghdr
- SizeofInet6Pktinfo = C.sizeof_struct_in6_pktinfo
- SizeofIPv6MTUInfo = C.sizeof_struct_ip6_mtuinfo
- SizeofICMPv6Filter = C.sizeof_struct_icmp6_filter
-)
-
-// Ptrace requests
-
-const (
- PTRACE_TRACEME = C.PT_TRACE_ME
- PTRACE_CONT = C.PT_CONTINUE
- PTRACE_KILL = C.PT_KILL
-)
-
-// Events (kqueue, kevent)
-
-type Kevent_t C.struct_kevent_freebsd11
-
-// Select
-
-type FdSet C.fd_set
-
-// Routing and interface messages
-
-const (
- sizeofIfMsghdr = C.sizeof_struct_if_msghdr
- SizeofIfMsghdr = C.sizeof_struct_if_msghdr8
- sizeofIfData = C.sizeof_struct_if_data
- SizeofIfData = C.sizeof_struct_if_data8
- SizeofIfaMsghdr = C.sizeof_struct_ifa_msghdr
- SizeofIfmaMsghdr = C.sizeof_struct_ifma_msghdr
- SizeofIfAnnounceMsghdr = C.sizeof_struct_if_announcemsghdr
- SizeofRtMsghdr = C.sizeof_struct_rt_msghdr
- SizeofRtMetrics = C.sizeof_struct_rt_metrics
-)
-
-type ifMsghdr C.struct_if_msghdr
-
-type IfMsghdr C.struct_if_msghdr8
-
-type ifData C.struct_if_data
-
-type IfData C.struct_if_data8
-
-type IfaMsghdr C.struct_ifa_msghdr
-
-type IfmaMsghdr C.struct_ifma_msghdr
-
-type IfAnnounceMsghdr C.struct_if_announcemsghdr
-
-type RtMsghdr C.struct_rt_msghdr
-
-type RtMetrics C.struct_rt_metrics
-
-// Berkeley packet filter
-
-const (
- SizeofBpfVersion = C.sizeof_struct_bpf_version
- SizeofBpfStat = C.sizeof_struct_bpf_stat
- SizeofBpfZbuf = C.sizeof_struct_bpf_zbuf
- SizeofBpfProgram = C.sizeof_struct_bpf_program
- SizeofBpfInsn = C.sizeof_struct_bpf_insn
- SizeofBpfHdr = C.sizeof_struct_bpf_hdr
- SizeofBpfZbufHeader = C.sizeof_struct_bpf_zbuf_header
-)
-
-type BpfVersion C.struct_bpf_version
-
-type BpfStat C.struct_bpf_stat
-
-type BpfZbuf C.struct_bpf_zbuf
-
-type BpfProgram C.struct_bpf_program
-
-type BpfInsn C.struct_bpf_insn
-
-type BpfHdr C.struct_bpf_hdr
-
-type BpfZbufHeader C.struct_bpf_zbuf_header
-
-// Terminal handling
-
-type Termios C.struct_termios
-
-type Winsize C.struct_winsize
-
-// fchmodat-like syscalls.
-
-const (
- AT_FDCWD = C.AT_FDCWD
- AT_REMOVEDIR = C.AT_REMOVEDIR
- AT_SYMLINK_FOLLOW = C.AT_SYMLINK_FOLLOW
- AT_SYMLINK_NOFOLLOW = C.AT_SYMLINK_NOFOLLOW
-)
-
-// poll
-
-type PollFd C.struct_pollfd
-
-const (
- POLLERR = C.POLLERR
- POLLHUP = C.POLLHUP
- POLLIN = C.POLLIN
- POLLINIGNEOF = C.POLLINIGNEOF
- POLLNVAL = C.POLLNVAL
- POLLOUT = C.POLLOUT
- POLLPRI = C.POLLPRI
- POLLRDBAND = C.POLLRDBAND
- POLLRDNORM = C.POLLRDNORM
- POLLWRBAND = C.POLLWRBAND
- POLLWRNORM = C.POLLWRNORM
-)
-
-// Capabilities
-
-type CapRights C.struct_cap_rights
-
-// Uname
-
-type Utsname C.struct_utsname
diff --git a/vendor/golang.org/x/sys/unix/types_netbsd.go b/vendor/golang.org/x/sys/unix/types_netbsd.go
deleted file mode 100644
index 2dd4f95..0000000
--- a/vendor/golang.org/x/sys/unix/types_netbsd.go
+++ /dev/null
@@ -1,289 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-/*
-Input to cgo -godefs. See README.md
-*/
-
-// +godefs map struct_in_addr [4]byte /* in_addr */
-// +godefs map struct_in6_addr [16]byte /* in6_addr */
-
-package unix
-
-/*
-#define KERNEL
-#include <dirent.h>
-#include <fcntl.h>
-#include <poll.h>
-#include <signal.h>
-#include <termios.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/event.h>
-#include <sys/mman.h>
-#include <sys/mount.h>
-#include <sys/ptrace.h>
-#include <sys/resource.h>
-#include <sys/select.h>
-#include <sys/signal.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/sysctl.h>
-#include <sys/time.h>
-#include <sys/uio.h>
-#include <sys/un.h>
-#include <sys/utsname.h>
-#include <sys/wait.h>
-#include <net/bpf.h>
-#include <net/if.h>
-#include <net/if_dl.h>
-#include <net/route.h>
-#include <netinet/in.h>
-#include <netinet/icmp6.h>
-#include <netinet/tcp.h>
-
-enum {
- sizeofPtr = sizeof(void*),
-};
-
-union sockaddr_all {
- struct sockaddr s1; // this one gets used for fields
- struct sockaddr_in s2; // these pad it out
- struct sockaddr_in6 s3;
- struct sockaddr_un s4;
- struct sockaddr_dl s5;
-};
-
-struct sockaddr_any {
- struct sockaddr addr;
- char pad[sizeof(union sockaddr_all) - sizeof(struct sockaddr)];
-};
-
-*/
-import "C"
-
-// Machine characteristics
-
-const (
- SizeofPtr = C.sizeofPtr
- SizeofShort = C.sizeof_short
- SizeofInt = C.sizeof_int
- SizeofLong = C.sizeof_long
- SizeofLongLong = C.sizeof_longlong
-)
-
-// Basic types
-
-type (
- _C_short C.short
- _C_int C.int
- _C_long C.long
- _C_long_long C.longlong
-)
-
-// Time
-
-type Timespec C.struct_timespec
-
-type Timeval C.struct_timeval
-
-// Processes
-
-type Rusage C.struct_rusage
-
-type Rlimit C.struct_rlimit
-
-type _Gid_t C.gid_t
-
-// Files
-
-type Stat_t C.struct_stat
-
-type Statfs_t C.struct_statfs
-
-type Flock_t C.struct_flock
-
-type Dirent C.struct_dirent
-
-type Fsid C.fsid_t
-
-// File system limits
-
-const (
- PathMax = C.PATH_MAX
-)
-
-// Advice to Fadvise
-
-const (
- FADV_NORMAL = C.POSIX_FADV_NORMAL
- FADV_RANDOM = C.POSIX_FADV_RANDOM
- FADV_SEQUENTIAL = C.POSIX_FADV_SEQUENTIAL
- FADV_WILLNEED = C.POSIX_FADV_WILLNEED
- FADV_DONTNEED = C.POSIX_FADV_DONTNEED
- FADV_NOREUSE = C.POSIX_FADV_NOREUSE
-)
-
-// Sockets
-
-type RawSockaddrInet4 C.struct_sockaddr_in
-
-type RawSockaddrInet6 C.struct_sockaddr_in6
-
-type RawSockaddrUnix C.struct_sockaddr_un
-
-type RawSockaddrDatalink C.struct_sockaddr_dl
-
-type RawSockaddr C.struct_sockaddr
-
-type RawSockaddrAny C.struct_sockaddr_any
-
-type _Socklen C.socklen_t
-
-type Linger C.struct_linger
-
-type Iovec C.struct_iovec
-
-type IPMreq C.struct_ip_mreq
-
-type IPv6Mreq C.struct_ipv6_mreq
-
-type Msghdr C.struct_msghdr
-
-type Cmsghdr C.struct_cmsghdr
-
-type Inet6Pktinfo C.struct_in6_pktinfo
-
-type IPv6MTUInfo C.struct_ip6_mtuinfo
-
-type ICMPv6Filter C.struct_icmp6_filter
-
-const (
- SizeofSockaddrInet4 = C.sizeof_struct_sockaddr_in
- SizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6
- SizeofSockaddrAny = C.sizeof_struct_sockaddr_any
- SizeofSockaddrUnix = C.sizeof_struct_sockaddr_un
- SizeofSockaddrDatalink = C.sizeof_struct_sockaddr_dl
- SizeofLinger = C.sizeof_struct_linger
- SizeofIPMreq = C.sizeof_struct_ip_mreq
- SizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq
- SizeofMsghdr = C.sizeof_struct_msghdr
- SizeofCmsghdr = C.sizeof_struct_cmsghdr
- SizeofInet6Pktinfo = C.sizeof_struct_in6_pktinfo
- SizeofIPv6MTUInfo = C.sizeof_struct_ip6_mtuinfo
- SizeofICMPv6Filter = C.sizeof_struct_icmp6_filter
-)
-
-// Ptrace requests
-
-const (
- PTRACE_TRACEME = C.PT_TRACE_ME
- PTRACE_CONT = C.PT_CONTINUE
- PTRACE_KILL = C.PT_KILL
-)
-
-// Events (kqueue, kevent)
-
-type Kevent_t C.struct_kevent
-
-// Select
-
-type FdSet C.fd_set
-
-// Routing and interface messages
-
-const (
- SizeofIfMsghdr = C.sizeof_struct_if_msghdr
- SizeofIfData = C.sizeof_struct_if_data
- SizeofIfaMsghdr = C.sizeof_struct_ifa_msghdr
- SizeofIfAnnounceMsghdr = C.sizeof_struct_if_announcemsghdr
- SizeofRtMsghdr = C.sizeof_struct_rt_msghdr
- SizeofRtMetrics = C.sizeof_struct_rt_metrics
-)
-
-type IfMsghdr C.struct_if_msghdr
-
-type IfData C.struct_if_data
-
-type IfaMsghdr C.struct_ifa_msghdr
-
-type IfAnnounceMsghdr C.struct_if_announcemsghdr
-
-type RtMsghdr C.struct_rt_msghdr
-
-type RtMetrics C.struct_rt_metrics
-
-type Mclpool C.struct_mclpool
-
-// Berkeley packet filter
-
-const (
- SizeofBpfVersion = C.sizeof_struct_bpf_version
- SizeofBpfStat = C.sizeof_struct_bpf_stat
- SizeofBpfProgram = C.sizeof_struct_bpf_program
- SizeofBpfInsn = C.sizeof_struct_bpf_insn
- SizeofBpfHdr = C.sizeof_struct_bpf_hdr
-)
-
-type BpfVersion C.struct_bpf_version
-
-type BpfStat C.struct_bpf_stat
-
-type BpfProgram C.struct_bpf_program
-
-type BpfInsn C.struct_bpf_insn
-
-type BpfHdr C.struct_bpf_hdr
-
-type BpfTimeval C.struct_bpf_timeval
-
-// Terminal handling
-
-type Termios C.struct_termios
-
-type Winsize C.struct_winsize
-
-type Ptmget C.struct_ptmget
-
-// fchmodat-like syscalls.
-
-const (
- AT_FDCWD = C.AT_FDCWD
- AT_SYMLINK_NOFOLLOW = C.AT_SYMLINK_NOFOLLOW
-)
-
-// poll
-
-type PollFd C.struct_pollfd
-
-const (
- POLLERR = C.POLLERR
- POLLHUP = C.POLLHUP
- POLLIN = C.POLLIN
- POLLNVAL = C.POLLNVAL
- POLLOUT = C.POLLOUT
- POLLPRI = C.POLLPRI
- POLLRDBAND = C.POLLRDBAND
- POLLRDNORM = C.POLLRDNORM
- POLLWRBAND = C.POLLWRBAND
- POLLWRNORM = C.POLLWRNORM
-)
-
-// Sysctl
-
-type Sysctlnode C.struct_sysctlnode
-
-// Uname
-
-type Utsname C.struct_utsname
-
-// Clockinfo
-
-const SizeofClockinfo = C.sizeof_struct_clockinfo
-
-type Clockinfo C.struct_clockinfo
diff --git a/vendor/golang.org/x/sys/unix/types_openbsd.go b/vendor/golang.org/x/sys/unix/types_openbsd.go
deleted file mode 100644
index 8aafbe4..0000000
--- a/vendor/golang.org/x/sys/unix/types_openbsd.go
+++ /dev/null
@@ -1,282 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-/*
-Input to cgo -godefs. See README.md
-*/
-
-// +godefs map struct_in_addr [4]byte /* in_addr */
-// +godefs map struct_in6_addr [16]byte /* in6_addr */
-
-package unix
-
-/*
-#define KERNEL
-#include <dirent.h>
-#include <fcntl.h>
-#include <poll.h>
-#include <signal.h>
-#include <termios.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/event.h>
-#include <sys/mman.h>
-#include <sys/mount.h>
-#include <sys/ptrace.h>
-#include <sys/resource.h>
-#include <sys/select.h>
-#include <sys/signal.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/uio.h>
-#include <sys/un.h>
-#include <sys/utsname.h>
-#include <sys/wait.h>
-#include <uvm/uvmexp.h>
-#include <net/bpf.h>
-#include <net/if.h>
-#include <net/if_dl.h>
-#include <net/route.h>
-#include <netinet/in.h>
-#include <netinet/icmp6.h>
-#include <netinet/tcp.h>
-
-enum {
- sizeofPtr = sizeof(void*),
-};
-
-union sockaddr_all {
- struct sockaddr s1; // this one gets used for fields
- struct sockaddr_in s2; // these pad it out
- struct sockaddr_in6 s3;
- struct sockaddr_un s4;
- struct sockaddr_dl s5;
-};
-
-struct sockaddr_any {
- struct sockaddr addr;
- char pad[sizeof(union sockaddr_all) - sizeof(struct sockaddr)];
-};
-
-*/
-import "C"
-
-// Machine characteristics
-
-const (
- SizeofPtr = C.sizeofPtr
- SizeofShort = C.sizeof_short
- SizeofInt = C.sizeof_int
- SizeofLong = C.sizeof_long
- SizeofLongLong = C.sizeof_longlong
-)
-
-// Basic types
-
-type (
- _C_short C.short
- _C_int C.int
- _C_long C.long
- _C_long_long C.longlong
-)
-
-// Time
-
-type Timespec C.struct_timespec
-
-type Timeval C.struct_timeval
-
-// Processes
-
-type Rusage C.struct_rusage
-
-type Rlimit C.struct_rlimit
-
-type _Gid_t C.gid_t
-
-// Files
-
-type Stat_t C.struct_stat
-
-type Statfs_t C.struct_statfs
-
-type Flock_t C.struct_flock
-
-type Dirent C.struct_dirent
-
-type Fsid C.fsid_t
-
-// File system limits
-
-const (
- PathMax = C.PATH_MAX
-)
-
-// Sockets
-
-type RawSockaddrInet4 C.struct_sockaddr_in
-
-type RawSockaddrInet6 C.struct_sockaddr_in6
-
-type RawSockaddrUnix C.struct_sockaddr_un
-
-type RawSockaddrDatalink C.struct_sockaddr_dl
-
-type RawSockaddr C.struct_sockaddr
-
-type RawSockaddrAny C.struct_sockaddr_any
-
-type _Socklen C.socklen_t
-
-type Linger C.struct_linger
-
-type Iovec C.struct_iovec
-
-type IPMreq C.struct_ip_mreq
-
-type IPv6Mreq C.struct_ipv6_mreq
-
-type Msghdr C.struct_msghdr
-
-type Cmsghdr C.struct_cmsghdr
-
-type Inet6Pktinfo C.struct_in6_pktinfo
-
-type IPv6MTUInfo C.struct_ip6_mtuinfo
-
-type ICMPv6Filter C.struct_icmp6_filter
-
-const (
- SizeofSockaddrInet4 = C.sizeof_struct_sockaddr_in
- SizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6
- SizeofSockaddrAny = C.sizeof_struct_sockaddr_any
- SizeofSockaddrUnix = C.sizeof_struct_sockaddr_un
- SizeofSockaddrDatalink = C.sizeof_struct_sockaddr_dl
- SizeofLinger = C.sizeof_struct_linger
- SizeofIPMreq = C.sizeof_struct_ip_mreq
- SizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq
- SizeofMsghdr = C.sizeof_struct_msghdr
- SizeofCmsghdr = C.sizeof_struct_cmsghdr
- SizeofInet6Pktinfo = C.sizeof_struct_in6_pktinfo
- SizeofIPv6MTUInfo = C.sizeof_struct_ip6_mtuinfo
- SizeofICMPv6Filter = C.sizeof_struct_icmp6_filter
-)
-
-// Ptrace requests
-
-const (
- PTRACE_TRACEME = C.PT_TRACE_ME
- PTRACE_CONT = C.PT_CONTINUE
- PTRACE_KILL = C.PT_KILL
-)
-
-// Events (kqueue, kevent)
-
-type Kevent_t C.struct_kevent
-
-// Select
-
-type FdSet C.fd_set
-
-// Routing and interface messages
-
-const (
- SizeofIfMsghdr = C.sizeof_struct_if_msghdr
- SizeofIfData = C.sizeof_struct_if_data
- SizeofIfaMsghdr = C.sizeof_struct_ifa_msghdr
- SizeofIfAnnounceMsghdr = C.sizeof_struct_if_announcemsghdr
- SizeofRtMsghdr = C.sizeof_struct_rt_msghdr
- SizeofRtMetrics = C.sizeof_struct_rt_metrics
-)
-
-type IfMsghdr C.struct_if_msghdr
-
-type IfData C.struct_if_data
-
-type IfaMsghdr C.struct_ifa_msghdr
-
-type IfAnnounceMsghdr C.struct_if_announcemsghdr
-
-type RtMsghdr C.struct_rt_msghdr
-
-type RtMetrics C.struct_rt_metrics
-
-type Mclpool C.struct_mclpool
-
-// Berkeley packet filter
-
-const (
- SizeofBpfVersion = C.sizeof_struct_bpf_version
- SizeofBpfStat = C.sizeof_struct_bpf_stat
- SizeofBpfProgram = C.sizeof_struct_bpf_program
- SizeofBpfInsn = C.sizeof_struct_bpf_insn
- SizeofBpfHdr = C.sizeof_struct_bpf_hdr
-)
-
-type BpfVersion C.struct_bpf_version
-
-type BpfStat C.struct_bpf_stat
-
-type BpfProgram C.struct_bpf_program
-
-type BpfInsn C.struct_bpf_insn
-
-type BpfHdr C.struct_bpf_hdr
-
-type BpfTimeval C.struct_bpf_timeval
-
-// Terminal handling
-
-type Termios C.struct_termios
-
-type Winsize C.struct_winsize
-
-// fchmodat-like syscalls.
-
-const (
- AT_FDCWD = C.AT_FDCWD
- AT_SYMLINK_NOFOLLOW = C.AT_SYMLINK_NOFOLLOW
-)
-
-// poll
-
-type PollFd C.struct_pollfd
-
-const (
- POLLERR = C.POLLERR
- POLLHUP = C.POLLHUP
- POLLIN = C.POLLIN
- POLLNVAL = C.POLLNVAL
- POLLOUT = C.POLLOUT
- POLLPRI = C.POLLPRI
- POLLRDBAND = C.POLLRDBAND
- POLLRDNORM = C.POLLRDNORM
- POLLWRBAND = C.POLLWRBAND
- POLLWRNORM = C.POLLWRNORM
-)
-
-// Signal Sets
-
-type Sigset_t C.sigset_t
-
-// Uname
-
-type Utsname C.struct_utsname
-
-// Uvmexp
-
-const SizeofUvmexp = C.sizeof_struct_uvmexp
-
-type Uvmexp C.struct_uvmexp
-
-// Clockinfo
-
-const SizeofClockinfo = C.sizeof_struct_clockinfo
-
-type Clockinfo C.struct_clockinfo
diff --git a/vendor/golang.org/x/sys/unix/types_solaris.go b/vendor/golang.org/x/sys/unix/types_solaris.go
deleted file mode 100644
index 2b716f9..0000000
--- a/vendor/golang.org/x/sys/unix/types_solaris.go
+++ /dev/null
@@ -1,266 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-/*
-Input to cgo -godefs. See README.md
-*/
-
-// +godefs map struct_in_addr [4]byte /* in_addr */
-// +godefs map struct_in6_addr [16]byte /* in6_addr */
-
-package unix
-
-/*
-#define KERNEL
-// These defines ensure that builds done on newer versions of Solaris are
-// backwards-compatible with older versions of Solaris and
-// OpenSolaris-based derivatives.
-#define __USE_SUNOS_SOCKETS__ // msghdr
-#define __USE_LEGACY_PROTOTYPES__ // iovec
-#include <dirent.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <limits.h>
-#include <poll.h>
-#include <signal.h>
-#include <termios.h>
-#include <termio.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#include <sys/mount.h>
-#include <sys/param.h>
-#include <sys/resource.h>
-#include <sys/select.h>
-#include <sys/signal.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/statvfs.h>
-#include <sys/time.h>
-#include <sys/times.h>
-#include <sys/types.h>
-#include <sys/utsname.h>
-#include <sys/un.h>
-#include <sys/wait.h>
-#include <net/bpf.h>
-#include <net/if.h>
-#include <net/if_dl.h>
-#include <net/route.h>
-#include <netinet/in.h>
-#include <netinet/icmp6.h>
-#include <netinet/tcp.h>
-#include <ustat.h>
-#include <utime.h>
-
-enum {
- sizeofPtr = sizeof(void*),
-};
-
-union sockaddr_all {
- struct sockaddr s1; // this one gets used for fields
- struct sockaddr_in s2; // these pad it out
- struct sockaddr_in6 s3;
- struct sockaddr_un s4;
- struct sockaddr_dl s5;
-};
-
-struct sockaddr_any {
- struct sockaddr addr;
- char pad[sizeof(union sockaddr_all) - sizeof(struct sockaddr)];
-};
-
-*/
-import "C"
-
-// Machine characteristics
-
-const (
- SizeofPtr = C.sizeofPtr
- SizeofShort = C.sizeof_short
- SizeofInt = C.sizeof_int
- SizeofLong = C.sizeof_long
- SizeofLongLong = C.sizeof_longlong
- PathMax = C.PATH_MAX
- MaxHostNameLen = C.MAXHOSTNAMELEN
-)
-
-// Basic types
-
-type (
- _C_short C.short
- _C_int C.int
- _C_long C.long
- _C_long_long C.longlong
-)
-
-// Time
-
-type Timespec C.struct_timespec
-
-type Timeval C.struct_timeval
-
-type Timeval32 C.struct_timeval32
-
-type Tms C.struct_tms
-
-type Utimbuf C.struct_utimbuf
-
-// Processes
-
-type Rusage C.struct_rusage
-
-type Rlimit C.struct_rlimit
-
-type _Gid_t C.gid_t
-
-// Files
-
-type Stat_t C.struct_stat
-
-type Flock_t C.struct_flock
-
-type Dirent C.struct_dirent
-
-// Filesystems
-
-type _Fsblkcnt_t C.fsblkcnt_t
-
-type Statvfs_t C.struct_statvfs
-
-// Sockets
-
-type RawSockaddrInet4 C.struct_sockaddr_in
-
-type RawSockaddrInet6 C.struct_sockaddr_in6
-
-type RawSockaddrUnix C.struct_sockaddr_un
-
-type RawSockaddrDatalink C.struct_sockaddr_dl
-
-type RawSockaddr C.struct_sockaddr
-
-type RawSockaddrAny C.struct_sockaddr_any
-
-type _Socklen C.socklen_t
-
-type Linger C.struct_linger
-
-type Iovec C.struct_iovec
-
-type IPMreq C.struct_ip_mreq
-
-type IPv6Mreq C.struct_ipv6_mreq
-
-type Msghdr C.struct_msghdr
-
-type Cmsghdr C.struct_cmsghdr
-
-type Inet6Pktinfo C.struct_in6_pktinfo
-
-type IPv6MTUInfo C.struct_ip6_mtuinfo
-
-type ICMPv6Filter C.struct_icmp6_filter
-
-const (
- SizeofSockaddrInet4 = C.sizeof_struct_sockaddr_in
- SizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6
- SizeofSockaddrAny = C.sizeof_struct_sockaddr_any
- SizeofSockaddrUnix = C.sizeof_struct_sockaddr_un
- SizeofSockaddrDatalink = C.sizeof_struct_sockaddr_dl
- SizeofLinger = C.sizeof_struct_linger
- SizeofIPMreq = C.sizeof_struct_ip_mreq
- SizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq
- SizeofMsghdr = C.sizeof_struct_msghdr
- SizeofCmsghdr = C.sizeof_struct_cmsghdr
- SizeofInet6Pktinfo = C.sizeof_struct_in6_pktinfo
- SizeofIPv6MTUInfo = C.sizeof_struct_ip6_mtuinfo
- SizeofICMPv6Filter = C.sizeof_struct_icmp6_filter
-)
-
-// Select
-
-type FdSet C.fd_set
-
-// Misc
-
-type Utsname C.struct_utsname
-
-type Ustat_t C.struct_ustat
-
-const (
- AT_FDCWD = C.AT_FDCWD
- AT_SYMLINK_NOFOLLOW = C.AT_SYMLINK_NOFOLLOW
- AT_SYMLINK_FOLLOW = C.AT_SYMLINK_FOLLOW
- AT_REMOVEDIR = C.AT_REMOVEDIR
- AT_EACCESS = C.AT_EACCESS
-)
-
-// Routing and interface messages
-
-const (
- SizeofIfMsghdr = C.sizeof_struct_if_msghdr
- SizeofIfData = C.sizeof_struct_if_data
- SizeofIfaMsghdr = C.sizeof_struct_ifa_msghdr
- SizeofRtMsghdr = C.sizeof_struct_rt_msghdr
- SizeofRtMetrics = C.sizeof_struct_rt_metrics
-)
-
-type IfMsghdr C.struct_if_msghdr
-
-type IfData C.struct_if_data
-
-type IfaMsghdr C.struct_ifa_msghdr
-
-type RtMsghdr C.struct_rt_msghdr
-
-type RtMetrics C.struct_rt_metrics
-
-// Berkeley packet filter
-
-const (
- SizeofBpfVersion = C.sizeof_struct_bpf_version
- SizeofBpfStat = C.sizeof_struct_bpf_stat
- SizeofBpfProgram = C.sizeof_struct_bpf_program
- SizeofBpfInsn = C.sizeof_struct_bpf_insn
- SizeofBpfHdr = C.sizeof_struct_bpf_hdr
-)
-
-type BpfVersion C.struct_bpf_version
-
-type BpfStat C.struct_bpf_stat
-
-type BpfProgram C.struct_bpf_program
-
-type BpfInsn C.struct_bpf_insn
-
-type BpfTimeval C.struct_bpf_timeval
-
-type BpfHdr C.struct_bpf_hdr
-
-// Terminal handling
-
-type Termios C.struct_termios
-
-type Termio C.struct_termio
-
-type Winsize C.struct_winsize
-
-// poll
-
-type PollFd C.struct_pollfd
-
-const (
- POLLERR = C.POLLERR
- POLLHUP = C.POLLHUP
- POLLIN = C.POLLIN
- POLLNVAL = C.POLLNVAL
- POLLOUT = C.POLLOUT
- POLLPRI = C.POLLPRI
- POLLRDBAND = C.POLLRDBAND
- POLLRDNORM = C.POLLRDNORM
- POLLWRBAND = C.POLLWRBAND
- POLLWRNORM = C.POLLWRNORM
-)
diff --git a/vendor/golang.org/x/text/unicode/bidi/gen.go b/vendor/golang.org/x/text/unicode/bidi/gen.go
deleted file mode 100644
index 4e1c7ba..0000000
--- a/vendor/golang.org/x/text/unicode/bidi/gen.go
+++ /dev/null
@@ -1,133 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-package main
-
-import (
- "flag"
- "log"
-
- "golang.org/x/text/internal/gen"
- "golang.org/x/text/internal/triegen"
- "golang.org/x/text/internal/ucd"
-)
-
-var outputFile = flag.String("out", "tables.go", "output file")
-
-func main() {
- gen.Init()
- gen.Repackage("gen_trieval.go", "trieval.go", "bidi")
- gen.Repackage("gen_ranges.go", "ranges_test.go", "bidi")
-
- genTables()
-}
-
-// bidiClass names and codes taken from class "bc" in
-// http://www.unicode.org/Public/8.0.0/ucd/PropertyValueAliases.txt
-var bidiClass = map[string]Class{
- "AL": AL, // ArabicLetter
- "AN": AN, // ArabicNumber
- "B": B, // ParagraphSeparator
- "BN": BN, // BoundaryNeutral
- "CS": CS, // CommonSeparator
- "EN": EN, // EuropeanNumber
- "ES": ES, // EuropeanSeparator
- "ET": ET, // EuropeanTerminator
- "L": L, // LeftToRight
- "NSM": NSM, // NonspacingMark
- "ON": ON, // OtherNeutral
- "R": R, // RightToLeft
- "S": S, // SegmentSeparator
- "WS": WS, // WhiteSpace
-
- "FSI": Control,
- "PDF": Control,
- "PDI": Control,
- "LRE": Control,
- "LRI": Control,
- "LRO": Control,
- "RLE": Control,
- "RLI": Control,
- "RLO": Control,
-}
-
-func genTables() {
- if numClass > 0x0F {
- log.Fatalf("Too many Class constants (%#x > 0x0F).", numClass)
- }
- w := gen.NewCodeWriter()
- defer w.WriteVersionedGoFile(*outputFile, "bidi")
-
- gen.WriteUnicodeVersion(w)
-
- t := triegen.NewTrie("bidi")
-
- // Build data about bracket mapping. These bits need to be or-ed with
- // any other bits.
- orMask := map[rune]uint64{}
-
- xorMap := map[rune]int{}
- xorMasks := []rune{0} // First value is no-op.
-
- ucd.Parse(gen.OpenUCDFile("BidiBrackets.txt"), func(p *ucd.Parser) {
- r1 := p.Rune(0)
- r2 := p.Rune(1)
- xor := r1 ^ r2
- if _, ok := xorMap[xor]; !ok {
- xorMap[xor] = len(xorMasks)
- xorMasks = append(xorMasks, xor)
- }
- entry := uint64(xorMap[xor]) << xorMaskShift
- switch p.String(2) {
- case "o":
- entry |= openMask
- case "c", "n":
- default:
- log.Fatalf("Unknown bracket class %q.", p.String(2))
- }
- orMask[r1] = entry
- })
-
- w.WriteComment(`
- xorMasks contains masks to be xor-ed with brackets to get the reverse
- version.`)
- w.WriteVar("xorMasks", xorMasks)
-
- done := map[rune]bool{}
-
- insert := func(r rune, c Class) {
- if !done[r] {
- t.Insert(r, orMask[r]|uint64(c))
- done[r] = true
- }
- }
-
- // Insert the derived BiDi properties.
- ucd.Parse(gen.OpenUCDFile("extracted/DerivedBidiClass.txt"), func(p *ucd.Parser) {
- r := p.Rune(0)
- class, ok := bidiClass[p.String(1)]
- if !ok {
- log.Fatalf("%U: Unknown BiDi class %q", r, p.String(1))
- }
- insert(r, class)
- })
- visitDefaults(insert)
-
- // TODO: use sparse blocks. This would reduce table size considerably
- // from the looks of it.
-
- sz, err := t.Gen(w)
- if err != nil {
- log.Fatal(err)
- }
- w.Size += sz
-}
-
-// dummy values to make methods in gen_common compile. The real versions
-// will be generated by this file to tables.go.
-var (
- xorMasks []rune
-)
diff --git a/vendor/golang.org/x/text/unicode/bidi/gen_ranges.go b/vendor/golang.org/x/text/unicode/bidi/gen_ranges.go
deleted file mode 100644
index 51bd68f..0000000
--- a/vendor/golang.org/x/text/unicode/bidi/gen_ranges.go
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-package main
-
-import (
- "unicode"
-
- "golang.org/x/text/internal/gen"
- "golang.org/x/text/internal/ucd"
- "golang.org/x/text/unicode/rangetable"
-)
-
-// These tables are hand-extracted from:
-// http://www.unicode.org/Public/8.0.0/ucd/extracted/DerivedBidiClass.txt
-func visitDefaults(fn func(r rune, c Class)) {
- // first write default values for ranges listed above.
- visitRunes(fn, AL, []rune{
- 0x0600, 0x07BF, // Arabic
- 0x08A0, 0x08FF, // Arabic Extended-A
- 0xFB50, 0xFDCF, // Arabic Presentation Forms
- 0xFDF0, 0xFDFF,
- 0xFE70, 0xFEFF,
- 0x0001EE00, 0x0001EEFF, // Arabic Mathematical Alpha Symbols
- })
- visitRunes(fn, R, []rune{
- 0x0590, 0x05FF, // Hebrew
- 0x07C0, 0x089F, // Nko et al.
- 0xFB1D, 0xFB4F,
- 0x00010800, 0x00010FFF, // Cypriot Syllabary et. al.
- 0x0001E800, 0x0001EDFF,
- 0x0001EF00, 0x0001EFFF,
- })
- visitRunes(fn, ET, []rune{ // European Terminator
- 0x20A0, 0x20Cf, // Currency symbols
- })
- rangetable.Visit(unicode.Noncharacter_Code_Point, func(r rune) {
- fn(r, BN) // Boundary Neutral
- })
- ucd.Parse(gen.OpenUCDFile("DerivedCoreProperties.txt"), func(p *ucd.Parser) {
- if p.String(1) == "Default_Ignorable_Code_Point" {
- fn(p.Rune(0), BN) // Boundary Neutral
- }
- })
-}
-
-func visitRunes(fn func(r rune, c Class), c Class, runes []rune) {
- for i := 0; i < len(runes); i += 2 {
- lo, hi := runes[i], runes[i+1]
- for j := lo; j <= hi; j++ {
- fn(j, c)
- }
- }
-}
diff --git a/vendor/golang.org/x/text/unicode/bidi/gen_trieval.go b/vendor/golang.org/x/text/unicode/bidi/gen_trieval.go
deleted file mode 100644
index 9cb9942..0000000
--- a/vendor/golang.org/x/text/unicode/bidi/gen_trieval.go
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-package main
-
-// Class is the Unicode BiDi class. Each rune has a single class.
-type Class uint
-
-const (
- L Class = iota // LeftToRight
- R // RightToLeft
- EN // EuropeanNumber
- ES // EuropeanSeparator
- ET // EuropeanTerminator
- AN // ArabicNumber
- CS // CommonSeparator
- B // ParagraphSeparator
- S // SegmentSeparator
- WS // WhiteSpace
- ON // OtherNeutral
- BN // BoundaryNeutral
- NSM // NonspacingMark
- AL // ArabicLetter
- Control // Control LRO - PDI
-
- numClass
-
- LRO // LeftToRightOverride
- RLO // RightToLeftOverride
- LRE // LeftToRightEmbedding
- RLE // RightToLeftEmbedding
- PDF // PopDirectionalFormat
- LRI // LeftToRightIsolate
- RLI // RightToLeftIsolate
- FSI // FirstStrongIsolate
- PDI // PopDirectionalIsolate
-
- unknownClass = ^Class(0)
-)
-
-var controlToClass = map[rune]Class{
- 0x202D: LRO, // LeftToRightOverride,
- 0x202E: RLO, // RightToLeftOverride,
- 0x202A: LRE, // LeftToRightEmbedding,
- 0x202B: RLE, // RightToLeftEmbedding,
- 0x202C: PDF, // PopDirectionalFormat,
- 0x2066: LRI, // LeftToRightIsolate,
- 0x2067: RLI, // RightToLeftIsolate,
- 0x2068: FSI, // FirstStrongIsolate,
- 0x2069: PDI, // PopDirectionalIsolate,
-}
-
-// A trie entry has the following bits:
-// 7..5 XOR mask for brackets
-// 4 1: Bracket open, 0: Bracket close
-// 3..0 Class type
-
-const (
- openMask = 0x10
- xorMaskShift = 5
-)
diff --git a/vendor/golang.org/x/text/unicode/norm/maketables.go b/vendor/golang.org/x/text/unicode/norm/maketables.go
deleted file mode 100644
index 338c395..0000000
--- a/vendor/golang.org/x/text/unicode/norm/maketables.go
+++ /dev/null
@@ -1,976 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-// Normalization table generator.
-// Data read from the web.
-// See forminfo.go for a description of the trie values associated with each rune.
-
-package main
-
-import (
- "bytes"
- "flag"
- "fmt"
- "io"
- "log"
- "sort"
- "strconv"
- "strings"
-
- "golang.org/x/text/internal/gen"
- "golang.org/x/text/internal/triegen"
- "golang.org/x/text/internal/ucd"
-)
-
-func main() {
- gen.Init()
- loadUnicodeData()
- compactCCC()
- loadCompositionExclusions()
- completeCharFields(FCanonical)
- completeCharFields(FCompatibility)
- computeNonStarterCounts()
- verifyComputed()
- printChars()
- testDerived()
- printTestdata()
- makeTables()
-}
-
-var (
- tablelist = flag.String("tables",
- "all",
- "comma-separated list of which tables to generate; "+
- "can be 'decomp', 'recomp', 'info' and 'all'")
- test = flag.Bool("test",
- false,
- "test existing tables against DerivedNormalizationProps and generate test data for regression testing")
- verbose = flag.Bool("verbose",
- false,
- "write data to stdout as it is parsed")
-)
-
-const MaxChar = 0x10FFFF // anything above this shouldn't exist
-
-// Quick Check properties of runes allow us to quickly
-// determine whether a rune may occur in a normal form.
-// For a given normal form, a rune may be guaranteed to occur
-// verbatim (QC=Yes), may or may not combine with another
-// rune (QC=Maybe), or may not occur (QC=No).
-type QCResult int
-
-const (
- QCUnknown QCResult = iota
- QCYes
- QCNo
- QCMaybe
-)
-
-func (r QCResult) String() string {
- switch r {
- case QCYes:
- return "Yes"
- case QCNo:
- return "No"
- case QCMaybe:
- return "Maybe"
- }
- return "***UNKNOWN***"
-}
-
-const (
- FCanonical = iota // NFC or NFD
- FCompatibility // NFKC or NFKD
- FNumberOfFormTypes
-)
-
-const (
- MComposed = iota // NFC or NFKC
- MDecomposed // NFD or NFKD
- MNumberOfModes
-)
-
-// This contains only the properties we're interested in.
-type Char struct {
- name string
- codePoint rune // if zero, this index is not a valid code point.
- ccc uint8 // canonical combining class
- origCCC uint8
- excludeInComp bool // from CompositionExclusions.txt
- compatDecomp bool // it has a compatibility expansion
-
- nTrailingNonStarters uint8
- nLeadingNonStarters uint8 // must be equal to trailing if non-zero
-
- forms [FNumberOfFormTypes]FormInfo // For FCanonical and FCompatibility
-
- state State
-}
-
-var chars = make([]Char, MaxChar+1)
-var cccMap = make(map[uint8]uint8)
-
-func (c Char) String() string {
- buf := new(bytes.Buffer)
-
- fmt.Fprintf(buf, "%U [%s]:\n", c.codePoint, c.name)
- fmt.Fprintf(buf, " ccc: %v\n", c.ccc)
- fmt.Fprintf(buf, " excludeInComp: %v\n", c.excludeInComp)
- fmt.Fprintf(buf, " compatDecomp: %v\n", c.compatDecomp)
- fmt.Fprintf(buf, " state: %v\n", c.state)
- fmt.Fprintf(buf, " NFC:\n")
- fmt.Fprint(buf, c.forms[FCanonical])
- fmt.Fprintf(buf, " NFKC:\n")
- fmt.Fprint(buf, c.forms[FCompatibility])
-
- return buf.String()
-}
-
-// In UnicodeData.txt, some ranges are marked like this:
-// 3400;<CJK Ideograph Extension A, First>;Lo;0;L;;;;;N;;;;;
-// 4DB5;<CJK Ideograph Extension A, Last>;Lo;0;L;;;;;N;;;;;
-// parseCharacter keeps a state variable indicating the weirdness.
-type State int
-
-const (
- SNormal State = iota // known to be zero for the type
- SFirst
- SLast
- SMissing
-)
-
-var lastChar = rune('\u0000')
-
-func (c Char) isValid() bool {
- return c.codePoint != 0 && c.state != SMissing
-}
-
-type FormInfo struct {
- quickCheck [MNumberOfModes]QCResult // index: MComposed or MDecomposed
- verified [MNumberOfModes]bool // index: MComposed or MDecomposed
-
- combinesForward bool // May combine with rune on the right
- combinesBackward bool // May combine with rune on the left
- isOneWay bool // Never appears in result
- inDecomp bool // Some decompositions result in this char.
- decomp Decomposition
- expandedDecomp Decomposition
-}
-
-func (f FormInfo) String() string {
- buf := bytes.NewBuffer(make([]byte, 0))
-
- fmt.Fprintf(buf, " quickCheck[C]: %v\n", f.quickCheck[MComposed])
- fmt.Fprintf(buf, " quickCheck[D]: %v\n", f.quickCheck[MDecomposed])
- fmt.Fprintf(buf, " cmbForward: %v\n", f.combinesForward)
- fmt.Fprintf(buf, " cmbBackward: %v\n", f.combinesBackward)
- fmt.Fprintf(buf, " isOneWay: %v\n", f.isOneWay)
- fmt.Fprintf(buf, " inDecomp: %v\n", f.inDecomp)
- fmt.Fprintf(buf, " decomposition: %X\n", f.decomp)
- fmt.Fprintf(buf, " expandedDecomp: %X\n", f.expandedDecomp)
-
- return buf.String()
-}
-
-type Decomposition []rune
-
-func parseDecomposition(s string, skipfirst bool) (a []rune, err error) {
- decomp := strings.Split(s, " ")
- if len(decomp) > 0 && skipfirst {
- decomp = decomp[1:]
- }
- for _, d := range decomp {
- point, err := strconv.ParseUint(d, 16, 64)
- if err != nil {
- return a, err
- }
- a = append(a, rune(point))
- }
- return a, nil
-}
-
-func loadUnicodeData() {
- f := gen.OpenUCDFile("UnicodeData.txt")
- defer f.Close()
- p := ucd.New(f)
- for p.Next() {
- r := p.Rune(ucd.CodePoint)
- char := &chars[r]
-
- char.ccc = uint8(p.Uint(ucd.CanonicalCombiningClass))
- decmap := p.String(ucd.DecompMapping)
-
- exp, err := parseDecomposition(decmap, false)
- isCompat := false
- if err != nil {
- if len(decmap) > 0 {
- exp, err = parseDecomposition(decmap, true)
- if err != nil {
- log.Fatalf(`%U: bad decomp |%v|: "%s"`, r, decmap, err)
- }
- isCompat = true
- }
- }
-
- char.name = p.String(ucd.Name)
- char.codePoint = r
- char.forms[FCompatibility].decomp = exp
- if !isCompat {
- char.forms[FCanonical].decomp = exp
- } else {
- char.compatDecomp = true
- }
- if len(decmap) > 0 {
- char.forms[FCompatibility].decomp = exp
- }
- }
- if err := p.Err(); err != nil {
- log.Fatal(err)
- }
-}
-
-// compactCCC converts the sparse set of CCC values to a continguous one,
-// reducing the number of bits needed from 8 to 6.
-func compactCCC() {
- m := make(map[uint8]uint8)
- for i := range chars {
- c := &chars[i]
- m[c.ccc] = 0
- }
- cccs := []int{}
- for v, _ := range m {
- cccs = append(cccs, int(v))
- }
- sort.Ints(cccs)
- for i, c := range cccs {
- cccMap[uint8(i)] = uint8(c)
- m[uint8(c)] = uint8(i)
- }
- for i := range chars {
- c := &chars[i]
- c.origCCC = c.ccc
- c.ccc = m[c.ccc]
- }
- if len(m) >= 1<<6 {
- log.Fatalf("too many difference CCC values: %d >= 64", len(m))
- }
-}
-
-// CompositionExclusions.txt has form:
-// 0958 # ...
-// See http://unicode.org/reports/tr44/ for full explanation
-func loadCompositionExclusions() {
- f := gen.OpenUCDFile("CompositionExclusions.txt")
- defer f.Close()
- p := ucd.New(f)
- for p.Next() {
- c := &chars[p.Rune(0)]
- if c.excludeInComp {
- log.Fatalf("%U: Duplicate entry in exclusions.", c.codePoint)
- }
- c.excludeInComp = true
- }
- if e := p.Err(); e != nil {
- log.Fatal(e)
- }
-}
-
-// hasCompatDecomp returns true if any of the recursive
-// decompositions contains a compatibility expansion.
-// In this case, the character may not occur in NFK*.
-func hasCompatDecomp(r rune) bool {
- c := &chars[r]
- if c.compatDecomp {
- return true
- }
- for _, d := range c.forms[FCompatibility].decomp {
- if hasCompatDecomp(d) {
- return true
- }
- }
- return false
-}
-
-// Hangul related constants.
-const (
- HangulBase = 0xAC00
- HangulEnd = 0xD7A4 // hangulBase + Jamo combinations (19 * 21 * 28)
-
- JamoLBase = 0x1100
- JamoLEnd = 0x1113
- JamoVBase = 0x1161
- JamoVEnd = 0x1176
- JamoTBase = 0x11A8
- JamoTEnd = 0x11C3
-
- JamoLVTCount = 19 * 21 * 28
- JamoTCount = 28
-)
-
-func isHangul(r rune) bool {
- return HangulBase <= r && r < HangulEnd
-}
-
-func isHangulWithoutJamoT(r rune) bool {
- if !isHangul(r) {
- return false
- }
- r -= HangulBase
- return r < JamoLVTCount && r%JamoTCount == 0
-}
-
-func ccc(r rune) uint8 {
- return chars[r].ccc
-}
-
-// Insert a rune in a buffer, ordered by Canonical Combining Class.
-func insertOrdered(b Decomposition, r rune) Decomposition {
- n := len(b)
- b = append(b, 0)
- cc := ccc(r)
- if cc > 0 {
- // Use bubble sort.
- for ; n > 0; n-- {
- if ccc(b[n-1]) <= cc {
- break
- }
- b[n] = b[n-1]
- }
- }
- b[n] = r
- return b
-}
-
-// Recursively decompose.
-func decomposeRecursive(form int, r rune, d Decomposition) Decomposition {
- dcomp := chars[r].forms[form].decomp
- if len(dcomp) == 0 {
- return insertOrdered(d, r)
- }
- for _, c := range dcomp {
- d = decomposeRecursive(form, c, d)
- }
- return d
-}
-
-func completeCharFields(form int) {
- // Phase 0: pre-expand decomposition.
- for i := range chars {
- f := &chars[i].forms[form]
- if len(f.decomp) == 0 {
- continue
- }
- exp := make(Decomposition, 0)
- for _, c := range f.decomp {
- exp = decomposeRecursive(form, c, exp)
- }
- f.expandedDecomp = exp
- }
-
- // Phase 1: composition exclusion, mark decomposition.
- for i := range chars {
- c := &chars[i]
- f := &c.forms[form]
-
- // Marks script-specific exclusions and version restricted.
- f.isOneWay = c.excludeInComp
-
- // Singletons
- f.isOneWay = f.isOneWay || len(f.decomp) == 1
-
- // Non-starter decompositions
- if len(f.decomp) > 1 {
- chk := c.ccc != 0 || chars[f.decomp[0]].ccc != 0
- f.isOneWay = f.isOneWay || chk
- }
-
- // Runes that decompose into more than two runes.
- f.isOneWay = f.isOneWay || len(f.decomp) > 2
-
- if form == FCompatibility {
- f.isOneWay = f.isOneWay || hasCompatDecomp(c.codePoint)
- }
-
- for _, r := range f.decomp {
- chars[r].forms[form].inDecomp = true
- }
- }
-
- // Phase 2: forward and backward combining.
- for i := range chars {
- c := &chars[i]
- f := &c.forms[form]
-
- if !f.isOneWay && len(f.decomp) == 2 {
- f0 := &chars[f.decomp[0]].forms[form]
- f1 := &chars[f.decomp[1]].forms[form]
- if !f0.isOneWay {
- f0.combinesForward = true
- }
- if !f1.isOneWay {
- f1.combinesBackward = true
- }
- }
- if isHangulWithoutJamoT(rune(i)) {
- f.combinesForward = true
- }
- }
-
- // Phase 3: quick check values.
- for i := range chars {
- c := &chars[i]
- f := &c.forms[form]
-
- switch {
- case len(f.decomp) > 0:
- f.quickCheck[MDecomposed] = QCNo
- case isHangul(rune(i)):
- f.quickCheck[MDecomposed] = QCNo
- default:
- f.quickCheck[MDecomposed] = QCYes
- }
- switch {
- case f.isOneWay:
- f.quickCheck[MComposed] = QCNo
- case (i & 0xffff00) == JamoLBase:
- f.quickCheck[MComposed] = QCYes
- if JamoLBase <= i && i < JamoLEnd {
- f.combinesForward = true
- }
- if JamoVBase <= i && i < JamoVEnd {
- f.quickCheck[MComposed] = QCMaybe
- f.combinesBackward = true
- f.combinesForward = true
- }
- if JamoTBase <= i && i < JamoTEnd {
- f.quickCheck[MComposed] = QCMaybe
- f.combinesBackward = true
- }
- case !f.combinesBackward:
- f.quickCheck[MComposed] = QCYes
- default:
- f.quickCheck[MComposed] = QCMaybe
- }
- }
-}
-
-func computeNonStarterCounts() {
- // Phase 4: leading and trailing non-starter count
- for i := range chars {
- c := &chars[i]
-
- runes := []rune{rune(i)}
- // We always use FCompatibility so that the CGJ insertion points do not
- // change for repeated normalizations with different forms.
- if exp := c.forms[FCompatibility].expandedDecomp; len(exp) > 0 {
- runes = exp
- }
- // We consider runes that combine backwards to be non-starters for the
- // purpose of Stream-Safe Text Processing.
- for _, r := range runes {
- if cr := &chars[r]; cr.ccc == 0 && !cr.forms[FCompatibility].combinesBackward {
- break
- }
- c.nLeadingNonStarters++
- }
- for i := len(runes) - 1; i >= 0; i-- {
- if cr := &chars[runes[i]]; cr.ccc == 0 && !cr.forms[FCompatibility].combinesBackward {
- break
- }
- c.nTrailingNonStarters++
- }
- if c.nTrailingNonStarters > 3 {
- log.Fatalf("%U: Decomposition with more than 3 (%d) trailing modifiers (%U)", i, c.nTrailingNonStarters, runes)
- }
-
- if isHangul(rune(i)) {
- c.nTrailingNonStarters = 2
- if isHangulWithoutJamoT(rune(i)) {
- c.nTrailingNonStarters = 1
- }
- }
-
- if l, t := c.nLeadingNonStarters, c.nTrailingNonStarters; l > 0 && l != t {
- log.Fatalf("%U: number of leading and trailing non-starters should be equal (%d vs %d)", i, l, t)
- }
- if t := c.nTrailingNonStarters; t > 3 {
- log.Fatalf("%U: number of trailing non-starters is %d > 3", t)
- }
- }
-}
-
-func printBytes(w io.Writer, b []byte, name string) {
- fmt.Fprintf(w, "// %s: %d bytes\n", name, len(b))
- fmt.Fprintf(w, "var %s = [...]byte {", name)
- for i, c := range b {
- switch {
- case i%64 == 0:
- fmt.Fprintf(w, "\n// Bytes %x - %x\n", i, i+63)
- case i%8 == 0:
- fmt.Fprintf(w, "\n")
- }
- fmt.Fprintf(w, "0x%.2X, ", c)
- }
- fmt.Fprint(w, "\n}\n\n")
-}
-
-// See forminfo.go for format.
-func makeEntry(f *FormInfo, c *Char) uint16 {
- e := uint16(0)
- if r := c.codePoint; HangulBase <= r && r < HangulEnd {
- e |= 0x40
- }
- if f.combinesForward {
- e |= 0x20
- }
- if f.quickCheck[MDecomposed] == QCNo {
- e |= 0x4
- }
- switch f.quickCheck[MComposed] {
- case QCYes:
- case QCNo:
- e |= 0x10
- case QCMaybe:
- e |= 0x18
- default:
- log.Fatalf("Illegal quickcheck value %v.", f.quickCheck[MComposed])
- }
- e |= uint16(c.nTrailingNonStarters)
- return e
-}
-
-// decompSet keeps track of unique decompositions, grouped by whether
-// the decomposition is followed by a trailing and/or leading CCC.
-type decompSet [7]map[string]bool
-
-const (
- normalDecomp = iota
- firstMulti
- firstCCC
- endMulti
- firstLeadingCCC
- firstCCCZeroExcept
- firstStarterWithNLead
- lastDecomp
-)
-
-var cname = []string{"firstMulti", "firstCCC", "endMulti", "firstLeadingCCC", "firstCCCZeroExcept", "firstStarterWithNLead", "lastDecomp"}
-
-func makeDecompSet() decompSet {
- m := decompSet{}
- for i := range m {
- m[i] = make(map[string]bool)
- }
- return m
-}
-func (m *decompSet) insert(key int, s string) {
- m[key][s] = true
-}
-
-func printCharInfoTables(w io.Writer) int {
- mkstr := func(r rune, f *FormInfo) (int, string) {
- d := f.expandedDecomp
- s := string([]rune(d))
- if max := 1 << 6; len(s) >= max {
- const msg = "%U: too many bytes in decomposition: %d >= %d"
- log.Fatalf(msg, r, len(s), max)
- }
- head := uint8(len(s))
- if f.quickCheck[MComposed] != QCYes {
- head |= 0x40
- }
- if f.combinesForward {
- head |= 0x80
- }
- s = string([]byte{head}) + s
-
- lccc := ccc(d[0])
- tccc := ccc(d[len(d)-1])
- cc := ccc(r)
- if cc != 0 && lccc == 0 && tccc == 0 {
- log.Fatalf("%U: trailing and leading ccc are 0 for non-zero ccc %d", r, cc)
- }
- if tccc < lccc && lccc != 0 {
- const msg = "%U: lccc (%d) must be <= tcc (%d)"
- log.Fatalf(msg, r, lccc, tccc)
- }
- index := normalDecomp
- nTrail := chars[r].nTrailingNonStarters
- nLead := chars[r].nLeadingNonStarters
- if tccc > 0 || lccc > 0 || nTrail > 0 {
- tccc <<= 2
- tccc |= nTrail
- s += string([]byte{tccc})
- index = endMulti
- for _, r := range d[1:] {
- if ccc(r) == 0 {
- index = firstCCC
- }
- }
- if lccc > 0 || nLead > 0 {
- s += string([]byte{lccc})
- if index == firstCCC {
- log.Fatalf("%U: multi-segment decomposition not supported for decompositions with leading CCC != 0", r)
- }
- index = firstLeadingCCC
- }
- if cc != lccc {
- if cc != 0 {
- log.Fatalf("%U: for lccc != ccc, expected ccc to be 0; was %d", r, cc)
- }
- index = firstCCCZeroExcept
- }
- } else if len(d) > 1 {
- index = firstMulti
- }
- return index, s
- }
-
- decompSet := makeDecompSet()
- const nLeadStr = "\x00\x01" // 0-byte length and tccc with nTrail.
- decompSet.insert(firstStarterWithNLead, nLeadStr)
-
- // Store the uniqued decompositions in a byte buffer,
- // preceded by their byte length.
- for _, c := range chars {
- for _, f := range c.forms {
- if len(f.expandedDecomp) == 0 {
- continue
- }
- if f.combinesBackward {
- log.Fatalf("%U: combinesBackward and decompose", c.codePoint)
- }
- index, s := mkstr(c.codePoint, &f)
- decompSet.insert(index, s)
- }
- }
-
- decompositions := bytes.NewBuffer(make([]byte, 0, 10000))
- size := 0
- positionMap := make(map[string]uint16)
- decompositions.WriteString("\000")
- fmt.Fprintln(w, "const (")
- for i, m := range decompSet {
- sa := []string{}
- for s := range m {
- sa = append(sa, s)
- }
- sort.Strings(sa)
- for _, s := range sa {
- p := decompositions.Len()
- decompositions.WriteString(s)
- positionMap[s] = uint16(p)
- }
- if cname[i] != "" {
- fmt.Fprintf(w, "%s = 0x%X\n", cname[i], decompositions.Len())
- }
- }
- fmt.Fprintln(w, "maxDecomp = 0x8000")
- fmt.Fprintln(w, ")")
- b := decompositions.Bytes()
- printBytes(w, b, "decomps")
- size += len(b)
-
- varnames := []string{"nfc", "nfkc"}
- for i := 0; i < FNumberOfFormTypes; i++ {
- trie := triegen.NewTrie(varnames[i])
-
- for r, c := range chars {
- f := c.forms[i]
- d := f.expandedDecomp
- if len(d) != 0 {
- _, key := mkstr(c.codePoint, &f)
- trie.Insert(rune(r), uint64(positionMap[key]))
- if c.ccc != ccc(d[0]) {
- // We assume the lead ccc of a decomposition !=0 in this case.
- if ccc(d[0]) == 0 {
- log.Fatalf("Expected leading CCC to be non-zero; ccc is %d", c.ccc)
- }
- }
- } else if c.nLeadingNonStarters > 0 && len(f.expandedDecomp) == 0 && c.ccc == 0 && !f.combinesBackward {
- // Handle cases where it can't be detected that the nLead should be equal
- // to nTrail.
- trie.Insert(c.codePoint, uint64(positionMap[nLeadStr]))
- } else if v := makeEntry(&f, &c)<<8 | uint16(c.ccc); v != 0 {
- trie.Insert(c.codePoint, uint64(0x8000|v))
- }
- }
- sz, err := trie.Gen(w, triegen.Compact(&normCompacter{name: varnames[i]}))
- if err != nil {
- log.Fatal(err)
- }
- size += sz
- }
- return size
-}
-
-func contains(sa []string, s string) bool {
- for _, a := range sa {
- if a == s {
- return true
- }
- }
- return false
-}
-
-func makeTables() {
- w := &bytes.Buffer{}
-
- size := 0
- if *tablelist == "" {
- return
- }
- list := strings.Split(*tablelist, ",")
- if *tablelist == "all" {
- list = []string{"recomp", "info"}
- }
-
- // Compute maximum decomposition size.
- max := 0
- for _, c := range chars {
- if n := len(string(c.forms[FCompatibility].expandedDecomp)); n > max {
- max = n
- }
- }
-
- fmt.Fprintln(w, "const (")
- fmt.Fprintln(w, "\t// Version is the Unicode edition from which the tables are derived.")
- fmt.Fprintf(w, "\tVersion = %q\n", gen.UnicodeVersion())
- fmt.Fprintln(w)
- fmt.Fprintln(w, "\t// MaxTransformChunkSize indicates the maximum number of bytes that Transform")
- fmt.Fprintln(w, "\t// may need to write atomically for any Form. Making a destination buffer at")
- fmt.Fprintln(w, "\t// least this size ensures that Transform can always make progress and that")
- fmt.Fprintln(w, "\t// the user does not need to grow the buffer on an ErrShortDst.")
- fmt.Fprintf(w, "\tMaxTransformChunkSize = %d+maxNonStarters*4\n", len(string(0x034F))+max)
- fmt.Fprintln(w, ")\n")
-
- // Print the CCC remap table.
- size += len(cccMap)
- fmt.Fprintf(w, "var ccc = [%d]uint8{", len(cccMap))
- for i := 0; i < len(cccMap); i++ {
- if i%8 == 0 {
- fmt.Fprintln(w)
- }
- fmt.Fprintf(w, "%3d, ", cccMap[uint8(i)])
- }
- fmt.Fprintln(w, "\n}\n")
-
- if contains(list, "info") {
- size += printCharInfoTables(w)
- }
-
- if contains(list, "recomp") {
- // Note that we use 32 bit keys, instead of 64 bit.
- // This clips the bits of three entries, but we know
- // this won't cause a collision. The compiler will catch
- // any changes made to UnicodeData.txt that introduces
- // a collision.
- // Note that the recomposition map for NFC and NFKC
- // are identical.
-
- // Recomposition map
- nrentries := 0
- for _, c := range chars {
- f := c.forms[FCanonical]
- if !f.isOneWay && len(f.decomp) > 0 {
- nrentries++
- }
- }
- sz := nrentries * 8
- size += sz
- fmt.Fprintf(w, "// recompMap: %d bytes (entries only)\n", sz)
- fmt.Fprintln(w, "var recompMap = map[uint32]rune{")
- for i, c := range chars {
- f := c.forms[FCanonical]
- d := f.decomp
- if !f.isOneWay && len(d) > 0 {
- key := uint32(uint16(d[0]))<<16 + uint32(uint16(d[1]))
- fmt.Fprintf(w, "0x%.8X: 0x%.4X,\n", key, i)
- }
- }
- fmt.Fprintf(w, "}\n\n")
- }
-
- fmt.Fprintf(w, "// Total size of tables: %dKB (%d bytes)\n", (size+512)/1024, size)
- gen.WriteVersionedGoFile("tables.go", "norm", w.Bytes())
-}
-
-func printChars() {
- if *verbose {
- for _, c := range chars {
- if !c.isValid() || c.state == SMissing {
- continue
- }
- fmt.Println(c)
- }
- }
-}
-
-// verifyComputed does various consistency tests.
-func verifyComputed() {
- for i, c := range chars {
- for _, f := range c.forms {
- isNo := (f.quickCheck[MDecomposed] == QCNo)
- if (len(f.decomp) > 0) != isNo && !isHangul(rune(i)) {
- log.Fatalf("%U: NF*D QC must be No if rune decomposes", i)
- }
-
- isMaybe := f.quickCheck[MComposed] == QCMaybe
- if f.combinesBackward != isMaybe {
- log.Fatalf("%U: NF*C QC must be Maybe if combinesBackward", i)
- }
- if len(f.decomp) > 0 && f.combinesForward && isMaybe {
- log.Fatalf("%U: NF*C QC must be Yes or No if combinesForward and decomposes", i)
- }
-
- if len(f.expandedDecomp) != 0 {
- continue
- }
- if a, b := c.nLeadingNonStarters > 0, (c.ccc > 0 || f.combinesBackward); a != b {
- // We accept these runes to be treated differently (it only affects
- // segment breaking in iteration, most likely on improper use), but
- // reconsider if more characters are added.
- // U+FF9E HALFWIDTH KATAKANA VOICED SOUND MARK;Lm;0;L;<narrow> 3099;;;;N;;;;;
- // U+FF9F HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK;Lm;0;L;<narrow> 309A;;;;N;;;;;
- // U+3133 HANGUL LETTER KIYEOK-SIOS;Lo;0;L;<compat> 11AA;;;;N;HANGUL LETTER GIYEOG SIOS;;;;
- // U+318E HANGUL LETTER ARAEAE;Lo;0;L;<compat> 11A1;;;;N;HANGUL LETTER ALAE AE;;;;
- // U+FFA3 HALFWIDTH HANGUL LETTER KIYEOK-SIOS;Lo;0;L;<narrow> 3133;;;;N;HALFWIDTH HANGUL LETTER GIYEOG SIOS;;;;
- // U+FFDC HALFWIDTH HANGUL LETTER I;Lo;0;L;<narrow> 3163;;;;N;;;;;
- if i != 0xFF9E && i != 0xFF9F && !(0x3133 <= i && i <= 0x318E) && !(0xFFA3 <= i && i <= 0xFFDC) {
- log.Fatalf("%U: nLead was %v; want %v", i, a, b)
- }
- }
- }
- nfc := c.forms[FCanonical]
- nfkc := c.forms[FCompatibility]
- if nfc.combinesBackward != nfkc.combinesBackward {
- log.Fatalf("%U: Cannot combine combinesBackward\n", c.codePoint)
- }
- }
-}
-
-// Use values in DerivedNormalizationProps.txt to compare against the
-// values we computed.
-// DerivedNormalizationProps.txt has form:
-// 00C0..00C5 ; NFD_QC; N # ...
-// 0374 ; NFD_QC; N # ...
-// See http://unicode.org/reports/tr44/ for full explanation
-func testDerived() {
- f := gen.OpenUCDFile("DerivedNormalizationProps.txt")
- defer f.Close()
- p := ucd.New(f)
- for p.Next() {
- r := p.Rune(0)
- c := &chars[r]
-
- var ftype, mode int
- qt := p.String(1)
- switch qt {
- case "NFC_QC":
- ftype, mode = FCanonical, MComposed
- case "NFD_QC":
- ftype, mode = FCanonical, MDecomposed
- case "NFKC_QC":
- ftype, mode = FCompatibility, MComposed
- case "NFKD_QC":
- ftype, mode = FCompatibility, MDecomposed
- default:
- continue
- }
- var qr QCResult
- switch p.String(2) {
- case "Y":
- qr = QCYes
- case "N":
- qr = QCNo
- case "M":
- qr = QCMaybe
- default:
- log.Fatalf(`Unexpected quick check value "%s"`, p.String(2))
- }
- if got := c.forms[ftype].quickCheck[mode]; got != qr {
- log.Printf("%U: FAILED %s (was %v need %v)\n", r, qt, got, qr)
- }
- c.forms[ftype].verified[mode] = true
- }
- if err := p.Err(); err != nil {
- log.Fatal(err)
- }
- // Any unspecified value must be QCYes. Verify this.
- for i, c := range chars {
- for j, fd := range c.forms {
- for k, qr := range fd.quickCheck {
- if !fd.verified[k] && qr != QCYes {
- m := "%U: FAIL F:%d M:%d (was %v need Yes) %s\n"
- log.Printf(m, i, j, k, qr, c.name)
- }
- }
- }
- }
-}
-
-var testHeader = `const (
- Yes = iota
- No
- Maybe
-)
-
-type formData struct {
- qc uint8
- combinesForward bool
- decomposition string
-}
-
-type runeData struct {
- r rune
- ccc uint8
- nLead uint8
- nTrail uint8
- f [2]formData // 0: canonical; 1: compatibility
-}
-
-func f(qc uint8, cf bool, dec string) [2]formData {
- return [2]formData{{qc, cf, dec}, {qc, cf, dec}}
-}
-
-func g(qc, qck uint8, cf, cfk bool, d, dk string) [2]formData {
- return [2]formData{{qc, cf, d}, {qck, cfk, dk}}
-}
-
-var testData = []runeData{
-`
-
-func printTestdata() {
- type lastInfo struct {
- ccc uint8
- nLead uint8
- nTrail uint8
- f string
- }
-
- last := lastInfo{}
- w := &bytes.Buffer{}
- fmt.Fprintf(w, testHeader)
- for r, c := range chars {
- f := c.forms[FCanonical]
- qc, cf, d := f.quickCheck[MComposed], f.combinesForward, string(f.expandedDecomp)
- f = c.forms[FCompatibility]
- qck, cfk, dk := f.quickCheck[MComposed], f.combinesForward, string(f.expandedDecomp)
- s := ""
- if d == dk && qc == qck && cf == cfk {
- s = fmt.Sprintf("f(%s, %v, %q)", qc, cf, d)
- } else {
- s = fmt.Sprintf("g(%s, %s, %v, %v, %q, %q)", qc, qck, cf, cfk, d, dk)
- }
- current := lastInfo{c.ccc, c.nLeadingNonStarters, c.nTrailingNonStarters, s}
- if last != current {
- fmt.Fprintf(w, "\t{0x%x, %d, %d, %d, %s},\n", r, c.origCCC, c.nLeadingNonStarters, c.nTrailingNonStarters, s)
- last = current
- }
- }
- fmt.Fprintln(w, "}")
- gen.WriteVersionedGoFile("data_test.go", "norm", w.Bytes())
-}
diff --git a/vendor/golang.org/x/text/unicode/norm/triegen.go b/vendor/golang.org/x/text/unicode/norm/triegen.go
deleted file mode 100644
index 45d7119..0000000
--- a/vendor/golang.org/x/text/unicode/norm/triegen.go
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-// Trie table generator.
-// Used by make*tables tools to generate a go file with trie data structures
-// for mapping UTF-8 to a 16-bit value. All but the last byte in a UTF-8 byte
-// sequence are used to lookup offsets in the index table to be used for the
-// next byte. The last byte is used to index into a table with 16-bit values.
-
-package main
-
-import (
- "fmt"
- "io"
-)
-
-const maxSparseEntries = 16
-
-type normCompacter struct {
- sparseBlocks [][]uint64
- sparseOffset []uint16
- sparseCount int
- name string
-}
-
-func mostFrequentStride(a []uint64) int {
- counts := make(map[int]int)
- var v int
- for _, x := range a {
- if stride := int(x) - v; v != 0 && stride >= 0 {
- counts[stride]++
- }
- v = int(x)
- }
- var maxs, maxc int
- for stride, cnt := range counts {
- if cnt > maxc || (cnt == maxc && stride < maxs) {
- maxs, maxc = stride, cnt
- }
- }
- return maxs
-}
-
-func countSparseEntries(a []uint64) int {
- stride := mostFrequentStride(a)
- var v, count int
- for _, tv := range a {
- if int(tv)-v != stride {
- if tv != 0 {
- count++
- }
- }
- v = int(tv)
- }
- return count
-}
-
-func (c *normCompacter) Size(v []uint64) (sz int, ok bool) {
- if n := countSparseEntries(v); n <= maxSparseEntries {
- return (n+1)*4 + 2, true
- }
- return 0, false
-}
-
-func (c *normCompacter) Store(v []uint64) uint32 {
- h := uint32(len(c.sparseOffset))
- c.sparseBlocks = append(c.sparseBlocks, v)
- c.sparseOffset = append(c.sparseOffset, uint16(c.sparseCount))
- c.sparseCount += countSparseEntries(v) + 1
- return h
-}
-
-func (c *normCompacter) Handler() string {
- return c.name + "Sparse.lookup"
-}
-
-func (c *normCompacter) Print(w io.Writer) (retErr error) {
- p := func(f string, x ...interface{}) {
- if _, err := fmt.Fprintf(w, f, x...); retErr == nil && err != nil {
- retErr = err
- }
- }
-
- ls := len(c.sparseBlocks)
- p("// %sSparseOffset: %d entries, %d bytes\n", c.name, ls, ls*2)
- p("var %sSparseOffset = %#v\n\n", c.name, c.sparseOffset)
-
- ns := c.sparseCount
- p("// %sSparseValues: %d entries, %d bytes\n", c.name, ns, ns*4)
- p("var %sSparseValues = [%d]valueRange {", c.name, ns)
- for i, b := range c.sparseBlocks {
- p("\n// Block %#x, offset %#x", i, c.sparseOffset[i])
- var v int
- stride := mostFrequentStride(b)
- n := countSparseEntries(b)
- p("\n{value:%#04x,lo:%#02x},", stride, uint8(n))
- for i, nv := range b {
- if int(nv)-v != stride {
- if v != 0 {
- p(",hi:%#02x},", 0x80+i-1)
- }
- if nv != 0 {
- p("\n{value:%#04x,lo:%#02x", nv, 0x80+i)
- }
- }
- v = int(nv)
- }
- if v != 0 {
- p(",hi:%#02x},", 0x80+len(b)-1)
- }
- }
- p("\n}\n\n")
- return
-}
diff --git a/vendor/gopkg.in/yaml.v2/.travis.yml b/vendor/gopkg.in/yaml.v2/.travis.yml
new file mode 100644
index 0000000..9f55693
--- /dev/null
+++ b/vendor/gopkg.in/yaml.v2/.travis.yml
@@ -0,0 +1,12 @@
+language: go
+
+go:
+ - 1.4
+ - 1.5
+ - 1.6
+ - 1.7
+ - 1.8
+ - 1.9
+ - tip
+
+go_import_path: gopkg.in/yaml.v2
diff --git a/vendor/gopkg.in/yaml.v2/LICENSE b/vendor/gopkg.in/yaml.v2/LICENSE
new file mode 100644
index 0000000..8dada3e
--- /dev/null
+++ b/vendor/gopkg.in/yaml.v2/LICENSE
@@ -0,0 +1,201 @@
+ 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
new file mode 100644
index 0000000..8da58fb
--- /dev/null
+++ b/vendor/gopkg.in/yaml.v2/LICENSE.libyaml
@@ -0,0 +1,31 @@
+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
new file mode 100644
index 0000000..866d74a
--- /dev/null
+++ b/vendor/gopkg.in/yaml.v2/NOTICE
@@ -0,0 +1,13 @@
+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
new file mode 100644
index 0000000..b50c6e8
--- /dev/null
+++ b/vendor/gopkg.in/yaml.v2/README.md
@@ -0,0 +1,133 @@
+# 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
new file mode 100644
index 0000000..1f7e87e
--- /dev/null
+++ b/vendor/gopkg.in/yaml.v2/apic.go
@@ -0,0 +1,739 @@
+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
+}
+
+// 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),
+ }
+}
+
+// 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
new file mode 100644
index 0000000..91679b5
--- /dev/null
+++ b/vendor/gopkg.in/yaml.v2/decode.go
@@ -0,0 +1,788 @@
+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
+}
+
+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) > 0.99 {
+ 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:
+ an, ok := d.doc.anchors[n.value]
+ if ok && an.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 {
+ an, ok := d.doc.anchors[ni.value]
+ if ok && an.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
new file mode 100644
index 0000000..a1c2cc5
--- /dev/null
+++ b/vendor/gopkg.in/yaml.v2/emitterc.go
@@ -0,0 +1,1685 @@
+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
new file mode 100644
index 0000000..0ee738e
--- /dev/null
+++ b/vendor/gopkg.in/yaml.v2/encode.go
@@ -0,0 +1,390 @@
+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/go.mod b/vendor/gopkg.in/yaml.v2/go.mod
new file mode 100644
index 0000000..1934e87
--- /dev/null
+++ b/vendor/gopkg.in/yaml.v2/go.mod
@@ -0,0 +1,5 @@
+module "gopkg.in/yaml.v2"
+
+require (
+ "gopkg.in/check.v1" v0.0.0-20161208181325-20d25e280405
+)
diff --git a/vendor/gopkg.in/yaml.v2/parserc.go b/vendor/gopkg.in/yaml.v2/parserc.go
new file mode 100644
index 0000000..81d05df
--- /dev/null
+++ b/vendor/gopkg.in/yaml.v2/parserc.go
@@ -0,0 +1,1095 @@
+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 <stream-start>", 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 <document start>", 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
new file mode 100644
index 0000000..7c1f5fa
--- /dev/null
+++ b/vendor/gopkg.in/yaml.v2/readerc.go
@@ -0,0 +1,412 @@
+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
new file mode 100644
index 0000000..4120e0c
--- /dev/null
+++ b/vendor/gopkg.in/yaml.v2/resolve.go
@@ -0,0 +1,258 @@
+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
new file mode 100644
index 0000000..077fd1d
--- /dev/null
+++ b/vendor/gopkg.in/yaml.v2/scannerc.go
@@ -0,0 +1,2696 @@
+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 {
+ // Check if we really need to fetch more tokens.
+ need_more_tokens := false
+
+ if parser.tokens_head == len(parser.tokens) {
+ // Queue is empty.
+ need_more_tokens = true
+ } else {
+ // Check if any potential simple key may occupy the head position.
+ if !yaml_parser_stale_simple_keys(parser) {
+ return false
+ }
+
+ for i := range parser.simple_keys {
+ simple_key := &parser.simple_keys[i]
+ if simple_key.possible && simple_key.token_number == parser.tokens_parsed {
+ need_more_tokens = true
+ break
+ }
+ }
+ }
+
+ // We are finished.
+ if !need_more_tokens {
+ 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
+ }
+
+ // Remove obsolete potential simple keys.
+ if !yaml_parser_stale_simple_keys(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")
+}
+
+// Check the list of potential simple keys and remove the positions that
+// cannot contain simple keys anymore.
+func yaml_parser_stale_simple_keys(parser *yaml_parser_t) bool {
+ // Check for a potential simple key for each flow level.
+ for i := range parser.simple_keys {
+ simple_key := &parser.simple_keys[i]
+
+ // The specification requires that a simple key
+ //
+ // - is limited to a single line,
+ // - is shorter than 1024 characters.
+ if simple_key.possible && (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 yaml_parser_set_scanner_error(parser,
+ "while scanning a simple key", simple_key.mark,
+ "could not find expected ':'")
+ }
+ simple_key.possible = false
+ }
+ }
+ return 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),
+ }
+ simple_key.mark = parser.mark
+
+ if !yaml_parser_remove_simple_key(parser) {
+ return false
+ }
+ parser.simple_keys[len(parser.simple_keys)-1] = simple_key
+ }
+ 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
+ return true
+}
+
+// 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{})
+
+ // Increase the flow level.
+ parser.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--
+ parser.simple_keys = parser.simple_keys[:len(parser.simple_keys)-1]
+ }
+ return true
+}
+
+// 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
+
+ // 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{})
+
+ // 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 simple_key.possible {
+ // 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
+
+ // 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
new file mode 100644
index 0000000..4c45e66
--- /dev/null
+++ b/vendor/gopkg.in/yaml.v2/sorter.go
@@ -0,0 +1,113 @@
+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
new file mode 100644
index 0000000..a2dde60
--- /dev/null
+++ b/vendor/gopkg.in/yaml.v2/writerc.go
@@ -0,0 +1,26 @@
+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
new file mode 100644
index 0000000..de85aa4
--- /dev/null
+++ b/vendor/gopkg.in/yaml.v2/yaml.go
@@ -0,0 +1,466 @@
+// 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 Decorder 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:"[<key>][,<flag1>[,<flag2>]]" (...)`
+//
+// 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 included if that method 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
+}
diff --git a/vendor/gopkg.in/yaml.v2/yamlh.go b/vendor/gopkg.in/yaml.v2/yamlh.go
new file mode 100644
index 0000000..e25cee5
--- /dev/null
+++ b/vendor/gopkg.in/yaml.v2/yamlh.go
@@ -0,0 +1,738 @@
+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 "<unknown token>"
+}
+
+// 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 "<unknown parser state>"
+}
+
+// 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.
+
+ // 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
new file mode 100644
index 0000000..8110ce3
--- /dev/null
+++ b/vendor/gopkg.in/yaml.v2/yamlprivateh.go
@@ -0,0 +1,173 @@
+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/modules.txt b/vendor/modules.txt
index a8b1f8f..6f46a7e 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -9,11 +9,11 @@
# github.com/eapache/queue v1.1.0
github.com/eapache/queue
# github.com/golang/protobuf v1.3.2
-github.com/golang/protobuf/ptypes/empty
github.com/golang/protobuf/proto
github.com/golang/protobuf/ptypes
github.com/golang/protobuf/ptypes/any
github.com/golang/protobuf/ptypes/duration
+github.com/golang/protobuf/ptypes/empty
github.com/golang/protobuf/ptypes/timestamp
# github.com/golang/snappy v0.0.1
github.com/golang/snappy
@@ -22,12 +22,14 @@
# github.com/jcmturner/gofork v0.0.0-20190328161633-dc7c13fece03
github.com/jcmturner/gofork/encoding/asn1
github.com/jcmturner/gofork/x/crypto/pbkdf2
+# github.com/jessevdk/go-flags v1.4.0
+github.com/jessevdk/go-flags
# github.com/klauspost/compress v1.9.7
-github.com/klauspost/compress/zstd
+github.com/klauspost/compress/fse
github.com/klauspost/compress/huff0
github.com/klauspost/compress/snappy
+github.com/klauspost/compress/zstd
github.com/klauspost/compress/zstd/internal/xxhash
-github.com/klauspost/compress/fse
# github.com/konsorten/go-windows-terminal-sequences v1.0.1
github.com/konsorten/go-windows-terminal-sequences
# github.com/pierrec/lz4 v2.2.6+incompatible
@@ -42,33 +44,35 @@
golang.org/x/crypto/pbkdf2
# golang.org/x/net v0.0.0-20191119073136-fc4aabc6c914
golang.org/x/net/context
-golang.org/x/net/proxy
-golang.org/x/net/trace
-golang.org/x/net/internal/socks
-golang.org/x/net/internal/timeseries
+golang.org/x/net/http/httpguts
golang.org/x/net/http2
golang.org/x/net/http2/hpack
-golang.org/x/net/http/httpguts
golang.org/x/net/idna
+golang.org/x/net/internal/socks
+golang.org/x/net/internal/timeseries
+golang.org/x/net/proxy
+golang.org/x/net/trace
# golang.org/x/sys v0.0.0-20190422165155-953cdadca894
golang.org/x/sys/unix
# golang.org/x/text v0.3.0
golang.org/x/text/secure/bidirule
+golang.org/x/text/transform
golang.org/x/text/unicode/bidi
golang.org/x/text/unicode/norm
-golang.org/x/text/transform
# google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c
google.golang.org/genproto/googleapis/rpc/status
# google.golang.org/grpc v1.27.0
google.golang.org/grpc
-google.golang.org/grpc/codes
-google.golang.org/grpc/status
+google.golang.org/grpc/attributes
google.golang.org/grpc/backoff
google.golang.org/grpc/balancer
google.golang.org/grpc/balancer/base
google.golang.org/grpc/balancer/roundrobin
+google.golang.org/grpc/binarylog/grpc_binarylog_v1
+google.golang.org/grpc/codes
google.golang.org/grpc/connectivity
google.golang.org/grpc/credentials
+google.golang.org/grpc/credentials/internal
google.golang.org/grpc/encoding
google.golang.org/grpc/encoding/proto
google.golang.org/grpc/grpclog
@@ -83,6 +87,7 @@
google.golang.org/grpc/internal/grpcsync
google.golang.org/grpc/internal/resolver/dns
google.golang.org/grpc/internal/resolver/passthrough
+google.golang.org/grpc/internal/syscall
google.golang.org/grpc/internal/transport
google.golang.org/grpc/keepalive
google.golang.org/grpc/metadata
@@ -91,11 +96,8 @@
google.golang.org/grpc/resolver
google.golang.org/grpc/serviceconfig
google.golang.org/grpc/stats
+google.golang.org/grpc/status
google.golang.org/grpc/tap
-google.golang.org/grpc/credentials/internal
-google.golang.org/grpc/binarylog/grpc_binarylog_v1
-google.golang.org/grpc/internal/syscall
-google.golang.org/grpc/attributes
# gopkg.in/jcmturner/aescts.v1 v1.0.1
gopkg.in/jcmturner/aescts.v1
# gopkg.in/jcmturner/dnsutils.v1 v1.0.1
@@ -105,32 +107,34 @@
gopkg.in/jcmturner/gokrb5.v7/client
gopkg.in/jcmturner/gokrb5.v7/config
gopkg.in/jcmturner/gokrb5.v7/credentials
-gopkg.in/jcmturner/gokrb5.v7/gssapi
-gopkg.in/jcmturner/gokrb5.v7/iana/chksumtype
-gopkg.in/jcmturner/gokrb5.v7/iana/keyusage
-gopkg.in/jcmturner/gokrb5.v7/keytab
-gopkg.in/jcmturner/gokrb5.v7/messages
-gopkg.in/jcmturner/gokrb5.v7/types
gopkg.in/jcmturner/gokrb5.v7/crypto
-gopkg.in/jcmturner/gokrb5.v7/crypto/etype
-gopkg.in/jcmturner/gokrb5.v7/iana/errorcode
-gopkg.in/jcmturner/gokrb5.v7/iana/flags
-gopkg.in/jcmturner/gokrb5.v7/iana/nametype
-gopkg.in/jcmturner/gokrb5.v7/iana/patype
-gopkg.in/jcmturner/gokrb5.v7/kadmin
-gopkg.in/jcmturner/gokrb5.v7/krberror
-gopkg.in/jcmturner/gokrb5.v7/iana/etypeID
-gopkg.in/jcmturner/gokrb5.v7/iana
-gopkg.in/jcmturner/gokrb5.v7/iana/adtype
-gopkg.in/jcmturner/gokrb5.v7/iana/asnAppTag
-gopkg.in/jcmturner/gokrb5.v7/iana/msgtype
-gopkg.in/jcmturner/gokrb5.v7/pac
-gopkg.in/jcmturner/gokrb5.v7/iana/addrtype
gopkg.in/jcmturner/gokrb5.v7/crypto/common
+gopkg.in/jcmturner/gokrb5.v7/crypto/etype
gopkg.in/jcmturner/gokrb5.v7/crypto/rfc3961
gopkg.in/jcmturner/gokrb5.v7/crypto/rfc3962
gopkg.in/jcmturner/gokrb5.v7/crypto/rfc4757
gopkg.in/jcmturner/gokrb5.v7/crypto/rfc8009
+gopkg.in/jcmturner/gokrb5.v7/gssapi
+gopkg.in/jcmturner/gokrb5.v7/iana
+gopkg.in/jcmturner/gokrb5.v7/iana/addrtype
+gopkg.in/jcmturner/gokrb5.v7/iana/adtype
+gopkg.in/jcmturner/gokrb5.v7/iana/asnAppTag
+gopkg.in/jcmturner/gokrb5.v7/iana/chksumtype
+gopkg.in/jcmturner/gokrb5.v7/iana/errorcode
+gopkg.in/jcmturner/gokrb5.v7/iana/etypeID
+gopkg.in/jcmturner/gokrb5.v7/iana/flags
+gopkg.in/jcmturner/gokrb5.v7/iana/keyusage
+gopkg.in/jcmturner/gokrb5.v7/iana/msgtype
+gopkg.in/jcmturner/gokrb5.v7/iana/nametype
+gopkg.in/jcmturner/gokrb5.v7/iana/patype
+gopkg.in/jcmturner/gokrb5.v7/kadmin
+gopkg.in/jcmturner/gokrb5.v7/keytab
+gopkg.in/jcmturner/gokrb5.v7/krberror
+gopkg.in/jcmturner/gokrb5.v7/messages
+gopkg.in/jcmturner/gokrb5.v7/pac
+gopkg.in/jcmturner/gokrb5.v7/types
# gopkg.in/jcmturner/rpc.v1 v1.1.0
gopkg.in/jcmturner/rpc.v1/mstypes
gopkg.in/jcmturner/rpc.v1/ndr
+# gopkg.in/yaml.v2 v2.2.3
+gopkg.in/yaml.v2