Merge pull request #511 from smira/dep-experiment

Convert to regular Go vendor + `dep` tool
This commit is contained in:
Andrey Smirnov
2017-03-22 20:34:36 +03:00
committed by GitHub
3261 changed files with 1742552 additions and 73 deletions

1
.gitignore vendored
View File

@@ -27,7 +27,6 @@ coverage*.out
*.pyc
vendor/
xc-out/
root/

40
Gomfile
View File

@@ -1,40 +0,0 @@
gom 'github.com/AlekSi/pointer', :commit => '5f6d527dae3d678b46fbb20331ddf44e2b841943'
gom 'github.com/awalterschulze/gographviz', :commit => '20d1f693416d9be045340150094aa42035a41c9e'
gom 'github.com/aws/aws-sdk-go', :commit => '2b26ad567f305510849d93c5d2025a8b561f2367'
gom 'github.com/cheggaaa/pb', :commit => '2c1b74620cc58a81ac152ee2d322e28c806d81ed'
gom 'github.com/DisposaBoy/JsonConfigReader', :commit => '33a99fdf1d5ee1f79b5077e9c06f955ad356d5f4'
gom 'github.com/gin-gonic/gin', :commit => 'b1758d3bfa09e61ddbc1c9a627e936eec6a170de'
gom 'github.com/go-ini/ini', :commit => 'afbd495e5aaea13597b5e14fe514ddeaa4d76fc3'
gom 'github.com/h2non/filetype/matchers', :commit => '259d9d2c52bc90dbd7e1999f9da86ee0d104d0ff'
gom 'github.com/jlaffaye/ftp', :commit => 'fec71e62e457557fbe85cefc847a048d57815d76'
gom 'github.com/jmespath/go-jmespath', :commit => '0b12d6b521d83fc7f755e7cfc1b1fbdd35a01a74'
gom 'github.com/julienschmidt/httprouter', :commit => '46807412fe50aaceb73bb57061c2230fd26a1640'
gom 'github.com/mattn/go-shellwords', :commit => 'c7ca6f94add751566a61cf2199e1de78d4c3eee4'
gom 'github.com/mkrautz/goar', :commit => '282caa8bd9daba480b51f1d5a988714913b97aad'
gom 'github.com/mxk/go-flowrate/flowrate', :commit => 'cca7078d478f8520f85629ad7c68962d31ed7682'
gom 'github.com/ncw/swift', :commit => 'b964f2ca856aac39885e258ad25aec08d5f64ee6'
gom 'github.com/smira/go-aws-auth', :commit => '0070896e9d7f4f9f2d558532b2d896ce2239992a'
gom 'github.com/smira/go-xz', :commit => '0c531f070014e218b21f3cfca801cc992d52726d'
gom 'github.com/smira/commander', :commit => 'f408b00e68d5d6e21b9f18bd310978dafc604e47'
gom 'github.com/smira/flag', :commit => '357ed3e599ffcbd4aeaa828e1d10da2df3ea5107'
gom 'github.com/smira/go-ftp-protocol/protocol', :commit => '066b75c2b70dca7ae10b1b88b47534a3c31ccfaa'
gom 'github.com/smira/go-uuid/uuid', :commit => 'ed3ca8a15a931b141440a7e98e4f716eec255f7d'
gom 'github.com/smira/lzma', :commit => '7f0af6269940baa2c938fabe73e0d7ba41205683'
gom 'github.com/golang/snappy', :commit => '723cc1e459b8eea2dea4583200fd60757d40097a'
gom 'github.com/syndtr/goleveldb/leveldb', :commit => '6b4daa5362b502898ddf367c5c11deb9e7a5c727'
gom 'github.com/ugorji/go/codec', :commit => '71c2886f5a673a35f909803f38ece5810165097b'
gom 'github.com/vaughan0/go-ini', :commit => 'a98ad7ee00ec53921f08832bc06ecf7fd600e6a1'
gom 'github.com/wsxiaoys/terminal/color', :commit => '5668e431776a7957528361f90ce828266c69ed08'
gom 'golang.org/x/crypto/ssh/terminal', :commit => 'a7ead6ddf06233883deca151dffaef2effbf498f'
gom 'golang.org/x/sys/unix', :commit => '7a6e5648d140666db5d920909e082ca00a87ba2c'
group :test do
gom 'gopkg.in/check.v1'
end
group :development do
gom 'github.com/golang/lint/golint'
gom 'github.com/mattn/goveralls'
gom 'github.com/axw/gocov/gocov'
gom 'golang.org/x/tools/cmd/cover'
end

View File

@@ -1,47 +1,45 @@
GOVERSION=$(shell go version | awk '{print $$3;}')
PACKAGES=context database deb files http query swift s3 utils
ALL_PACKAGES=api aptly context cmd console database deb files http query swift s3 utils
BINPATH=$(abspath ./vendor/bin)
GOM_ENVIRONMENT=-test
PYTHON?=python
TESTS?=
BINPATH?=$(GOPATH)/bin
ifeq ($(GOVERSION), devel)
TRAVIS_TARGET=coveralls
GOM_ENVIRONMENT+=-development
else
TRAVIS_TARGET=test
endif
ifeq ($(TRAVIS), true)
GOM=$(HOME)/gopath/bin/gom
else
GOM=gom
endif
all: test check system-test
prepare:
go get -u github.com/mattn/gom
$(GOM) $(GOM_ENVIRONMENT) install
go get -u github.com/mattn/goveralls
go get -u github.com/axw/gocov/gocov
go get -u golang.org/x/tools/cmd/cover
go get -u github.com/golang/lint/golint
dev:
go get -u github.com/golang/dep/...
go get -u github.com/laher/goxc
coverage.out:
rm -f coverage.*.out
for i in $(PACKAGES); do $(GOM) test -coverprofile=coverage.$$i.out -covermode=count ./$$i; done
for i in $(PACKAGES); do go test -coverprofile=coverage.$$i.out -covermode=count ./$$i; done
echo "mode: count" > coverage.out
grep -v -h "mode: count" coverage.*.out >> coverage.out
rm -f coverage.*.out
coverage: coverage.out
$(GOM) exec go tool cover -html=coverage.out
go tool cover -html=coverage.out
rm -f coverage.out
check:
$(GOM) exec go tool vet -all=true $(ALL_PACKAGES:%=./%)
$(GOM) exec golint $(ALL_PACKAGES:%=./%)
go vet -shadow=true $(ALL_PACKAGES:%=./%)
golint $(ALL_PACKAGES:%=./%)
install:
$(GOM) build -o $(BINPATH)/aptly
go install -v
system-test: install
if [ ! -e ~/aptly-fixture-db ]; then git clone https://github.com/aptly-dev/aptly-fixture-db.git ~/aptly-fixture-db/; fi
@@ -51,10 +49,10 @@ system-test: install
travis: $(TRAVIS_TARGET) system-test
test:
$(GOM) test -v `go list ./... | grep -v vendor/` -gocheck.v=true
go test -v `go list ./... | grep -v vendor/` -gocheck.v=true
coveralls: coverage.out
$(GOM) exec $(BINPATH)/goveralls -service travis-ci.org -coverprofile=coverage.out -repotoken=$(COVERALLS_TOKEN)
$(BINPATH)/goveralls -service travis-ci.org -coverprofile=coverage.out -repotoken=$(COVERALLS_TOKEN)
mem.png: mem.dat mem.gp
gnuplot mem.gp
@@ -64,9 +62,6 @@ src-package:
rm -rf aptly-$(VERSION)
mkdir -p aptly-$(VERSION)/src/github.com/smira/aptly/
cd aptly-$(VERSION)/src/github.com/smira/ && git clone https://github.com/smira/aptly && cd aptly && git checkout v$(VERSION)
cd aptly-$(VERSION)/src/github.com/smira/aptly && gom -production install
cd aptly-$(VERSION)/src/github.com/smira/aptly && find . \( -name .git -o -name .bzr -o -name .hg \) -print | xargs rm -rf
rm -rf aptly-$(VERSION)/src/github.com/smira/aptly/vendor/{pkg,bin}
mkdir -p aptly-$(VERSION)/bash_completion.d
(cd aptly-$(VERSION)/bash_completion.d && wget https://raw.github.com/aptly-dev/aptly-bash-completion/$(VERSION)/aptly)
tar cyf aptly-$(VERSION)-src.tar.bz2 aptly-$(VERSION)
@@ -79,7 +74,7 @@ goxc:
cp man/aptly.1 root/usr/share/man/man1
(cd root/etc/bash_completion.d && wget https://raw.github.com/aptly-dev/aptly-bash-completion/master/aptly)
gzip root/usr/share/man/man1/aptly.1
gom exec goxc -pv=$(VERSION) -max-processors=4 $(GOXC_OPTS)
goxc -pv=$(VERSION) -max-processors=4 $(GOXC_OPTS)
man:
make -C man

View File

@@ -66,17 +66,12 @@ Binary executables (depends almost only on libc) are available for download from
If you have Go environment set up, you can build aptly from source by running (go 1.6+ required)::
go get -u github.com/mattn/gom
mkdir -p $GOPATH/src/github.com/smira/aptly
git clone https://github.com/smira/aptly $GOPATH/src/github.com/smira/aptly
cd $GOPATH/src/github.com/smira/aptly
gom -production install
gom build -o $GOPATH/bin/aptly
go install .
Aptly is using `gom <https://github.com/mattn/gom>`_ to fix external dependencies, so regular ``go get github.com/smira/aptly``
should work as well, but might fail or produce different result (if external libraries got updated).
If you don't have Go installed (or older version), you can easily install Go using `gvm <https://github.com/moovweb/gvm/>`_.
Binary would be installed to ```$GOPATH/bin/aptly``.
Integrations
------------

292
lock.json Normal file
View File

@@ -0,0 +1,292 @@
{
"memo": "4ce49ad4105227467bccc48eec5832d84749da3dee8dc8f6574cd32fec3970c1",
"projects": [
{
"name": "github.com/AlekSi/pointer",
"version": "v1.0.0",
"revision": "08a25bac605b3fcb6cc27f3917b2c2c87451963d",
"packages": [
"."
]
},
{
"name": "github.com/DisposaBoy/JsonConfigReader",
"branch": "master",
"revision": "33a99fdf1d5ee1f79b5077e9c06f955ad356d5f4",
"packages": [
"."
]
},
{
"name": "github.com/awalterschulze/gographviz",
"version": "v1.0",
"revision": "761fd5fbb34e4c2c138c280395b65b48e4ff5a53",
"packages": [
".",
"ast",
"parser",
"scanner",
"token"
]
},
{
"name": "github.com/aws/aws-sdk-go",
"version": "v1.8.0",
"revision": "2db5849d2939d93075d911138309a83235032bea",
"packages": [
"aws",
"aws/awserr",
"aws/awsutil",
"aws/client",
"aws/client/metadata",
"aws/corehandlers",
"aws/credentials",
"aws/credentials/ec2rolecreds",
"aws/credentials/endpointcreds",
"aws/credentials/stscreds",
"aws/defaults",
"aws/ec2metadata",
"aws/endpoints",
"aws/request",
"aws/session",
"aws/signer/v4",
"private/protocol",
"private/protocol/query",
"private/protocol/query/queryutil",
"private/protocol/rest",
"private/protocol/restxml",
"private/protocol/xml/xmlutil",
"service/s3",
"service/sts"
]
},
{
"name": "github.com/cheggaaa/pb",
"version": "v1.0.10",
"revision": "cdf719fac0dd208251aa828e687c2d5802053b51",
"packages": [
"."
]
},
{
"name": "github.com/gin-gonic/gin",
"revision": "b1758d3bfa09e61ddbc1c9a627e936eec6a170de",
"packages": [
".",
"binding",
"render"
]
},
{
"name": "github.com/go-ini/ini",
"version": "v1.26.0",
"revision": "1730955e3146956d6a087861380f9b4667ed5071",
"packages": [
"."
]
},
{
"name": "github.com/golang/snappy",
"branch": "master",
"revision": "553a641470496b2327abcac10b36396bd98e45c9",
"packages": [
"."
]
},
{
"name": "github.com/h2non/filetype",
"branch": "master",
"revision": "0df83c38d14ff5f653d419d480eaac286ccbc823",
"packages": [
"matchers"
]
},
{
"name": "github.com/jlaffaye/ftp",
"branch": "master",
"revision": "7b85eb4638a2c0473acefcfb929a98f879c15c86",
"packages": [
"."
]
},
{
"name": "github.com/jmespath/go-jmespath",
"version": "0.2.2",
"revision": "3433f3ea46d9f8019119e7dd41274e112a2359a9",
"packages": [
"."
]
},
{
"name": "github.com/julienschmidt/httprouter",
"version": "v1.1",
"revision": "8c199fb6259ffc1af525cc3ad52ee60ba8359669",
"packages": [
"."
]
},
{
"name": "github.com/mattn/go-runewidth",
"version": "v0.0.2",
"revision": "9e777a8366cce605130a531d2cd6363d07ad7317",
"packages": [
"."
]
},
{
"name": "github.com/mattn/go-shellwords",
"version": "v1.0.2",
"revision": "005a0944d84452842197c2108bd9168ced206f78",
"packages": [
"."
]
},
{
"name": "github.com/mkrautz/goar",
"branch": "master",
"revision": "282caa8bd9daba480b51f1d5a988714913b97aad",
"packages": [
"."
]
},
{
"name": "github.com/mxk/go-flowrate",
"branch": "master",
"revision": "cca7078d478f8520f85629ad7c68962d31ed7682",
"packages": [
"flowrate"
]
},
{
"name": "github.com/ncw/swift",
"branch": "master",
"revision": "8e9b10220613abdbc2896808ee6b43e411a4fa6c",
"packages": [
".",
"swifttest"
]
},
{
"name": "github.com/smira/commander",
"branch": "master",
"revision": "f408b00e68d5d6e21b9f18bd310978dafc604e47",
"packages": [
"."
]
},
{
"name": "github.com/smira/flag",
"branch": "master",
"revision": "357ed3e599ffcbd4aeaa828e1d10da2df3ea5107",
"packages": [
"."
]
},
{
"name": "github.com/smira/go-aws-auth",
"branch": "master",
"revision": "0070896e9d7f4f9f2d558532b2d896ce2239992a",
"packages": [
"."
]
},
{
"name": "github.com/smira/go-ftp-protocol",
"branch": "master",
"revision": "066b75c2b70dca7ae10b1b88b47534a3c31ccfaa",
"packages": [
"protocol"
]
},
{
"name": "github.com/smira/go-uuid",
"branch": "master",
"revision": "ed3ca8a15a931b141440a7e98e4f716eec255f7d",
"packages": [
"uuid"
]
},
{
"name": "github.com/smira/go-xz",
"branch": "master",
"revision": "0c531f070014e218b21f3cfca801cc992d52726d",
"packages": [
"."
]
},
{
"name": "github.com/smira/lzma",
"branch": "master",
"revision": "7f0af6269940baa2c938fabe73e0d7ba41205683",
"packages": [
"."
]
},
{
"name": "github.com/syndtr/goleveldb",
"branch": "master",
"revision": "3c5717caf1475fd25964109a0fc640bd150fce43",
"packages": [
"leveldb",
"leveldb/cache",
"leveldb/comparer",
"leveldb/errors",
"leveldb/filter",
"leveldb/iterator",
"leveldb/journal",
"leveldb/memdb",
"leveldb/opt",
"leveldb/storage",
"leveldb/table",
"leveldb/util"
]
},
{
"name": "github.com/ugorji/go",
"revision": "71c2886f5a673a35f909803f38ece5810165097b",
"packages": [
"codec"
]
},
{
"name": "github.com/wsxiaoys/terminal",
"branch": "master",
"revision": "0940f3fc43a0ed42d04916b1c04578462c650b09",
"packages": [
"color"
]
},
{
"name": "golang.org/x/crypto",
"branch": "master",
"revision": "459e26527287adbc2adcc5d0d49abff9a5f315a7",
"packages": [
"ssh/terminal"
]
},
{
"name": "golang.org/x/sys",
"branch": "master",
"revision": "99f16d856c9836c42d24e7ab64ea72916925fa97",
"packages": [
"unix"
]
},
{
"name": "gopkg.in/check.v1",
"branch": "v1",
"revision": "20d25e2804050c1cd24a7eea1e7a6447dd0e74ec",
"packages": [
"."
]
},
{
"name": "gopkg.in/h2non/filetype.v1",
"version": "v1.0.1",
"revision": "3093b8ebec6efb56ac813238b8beab4ed4eaac6a",
"packages": [
"types"
]
}
]
}

View File

@@ -5,7 +5,6 @@ prepare:
gem specific_install -l smira/ronn
generate:
cd .. && gom build -o man/gen man/gen.go
./gen
go run gen.go
.PHONY: prepare generate

31
manifest.json Normal file
View File

@@ -0,0 +1,31 @@
{
"dependencies": {
"github.com/gin-gonic/gin": {
"revision": "b1758d3bfa09e61ddbc1c9a627e936eec6a170de"
},
"github.com/h2non/filetype": {
"branch": "master"
},
"github.com/mkrautz/goar": {
"branch": "master"
},
"github.com/smira/go-uuid": {
"branch": "master"
},
"github.com/smira/go-xz": {
"branch": "master"
},
"github.com/ugorji/go": {
"revision": "71c2886f5a673a35f909803f38ece5810165097b"
},
"golang.org/x/crypto": {
"branch": "master"
},
"golang.org/x/sys": {
"branch": "master"
},
"gopkg.in/check.v1": {
"branch": "v1"
}
}
}

View File

@@ -92,7 +92,8 @@ class FilesAPITestSecurity(APITest):
def check(self):
self.check_equal(self.delete("/api/files/.").status_code, 400)
self.check_equal(self.delete("/api/files").status_code, 404)
self.check_equal(self.delete("/api/files").status_code, 405)
self.check_equal(self.delete("/api/files/").status_code, 404)
self.check_equal(self.delete("/api/files/../.").status_code, 400)
self.check_equal(self.delete("/api/files/./..").status_code, 400)
self.check_equal(self.delete("/api/files/dir/..").status_code, 400)

9
vendor/github.com/AlekSi/pointer/.travis.yml generated vendored Normal file
View File

@@ -0,0 +1,9 @@
language: go
sudo: false
go:
- 1.6.4
- 1.7.4
- tip
script: go test -v

21
vendor/github.com/AlekSi/pointer/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2015 Alexey Palazhchenko
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.

42
vendor/github.com/AlekSi/pointer/README.md generated vendored Normal file
View File

@@ -0,0 +1,42 @@
# pointer [![GoDoc](https://godoc.org/github.com/AlekSi/pointer?status.svg)](https://godoc.org/github.com/AlekSi/pointer) [![Build Status](https://travis-ci.org/AlekSi/pointer.svg)](https://travis-ci.org/AlekSi/pointer)
Go package pointer provides helpers to get pointers to values of build-in types.
```
go get github.com/AlekSi/pointer
```
API is stable. [Documentation](http://godoc.org/github.com/AlekSi/pointer).
```go
package motivationalexample
import (
"encoding/json"
"github.com/AlekSi/pointer"
)
const (
defaultName = "some name"
)
// Stuff contains optional fields.
type Stuff struct {
Name *string
Comment *string
Value *int64
Time *time.Time
}
// SomeStuff makes some JSON-encoded stuff.
func SomeStuff() (data []byte, err error) {
return json.Marshal(&Stuff{
Name: pointer.ToString(defaultName), // can't say &defaultName
Comment: pointer.ToString("not yet"), // can't say &"not yet"
Value: pointer.ToInt64(42), // can't say &42 or &int64(42)
Time: pointer.ToTime(time.Date(2014, 6, 25, 12, 24, 40, 0, time.UTC)), // can't say &time.Date(…)
})
}
```

28
vendor/github.com/AlekSi/pointer/pointer.go generated vendored Normal file
View File

@@ -0,0 +1,28 @@
// Package pointer provides helpers to get pointers to values of build-in types.
package pointer // import "github.com/AlekSi/pointer"
import (
"time"
)
func ToBool(b bool) *bool { return &b }
func ToByte(b byte) *byte { return &b }
func ToComplex128(c complex128) *complex128 { return &c }
func ToComplex64(c complex64) *complex64 { return &c }
func ToError(e error) *error { return &e }
func ToFloat32(f float32) *float32 { return &f }
func ToFloat64(f float64) *float64 { return &f }
func ToInt(i int) *int { return &i }
func ToInt16(i int16) *int16 { return &i }
func ToInt32(i int32) *int32 { return &i }
func ToInt64(i int64) *int64 { return &i }
func ToInt8(i int8) *int8 { return &i }
func ToRune(r rune) *rune { return &r }
func ToString(s string) *string { return &s }
func ToTime(t time.Time) *time.Time { return &t }
func ToUint(u uint) *uint { return &u }
func ToUint16(u uint16) *uint16 { return &u }
func ToUint32(u uint32) *uint32 { return &u }
func ToUint64(u uint64) *uint64 { return &u }
func ToUint8(u uint8) *uint8 { return &u }
func ToUintptr(u uintptr) *uintptr { return &u }

180
vendor/github.com/AlekSi/pointer/pointer_test.go generated vendored Normal file
View File

@@ -0,0 +1,180 @@
package pointer
import (
"encoding/json"
"fmt"
"testing"
"time"
)
func TestBool(t *testing.T) {
var x bool
if *ToBool(x) != x {
t.Fail()
}
}
func TestByte(t *testing.T) {
var x byte
if *ToByte(x) != x {
t.Fail()
}
}
func TestComplex128(t *testing.T) {
var x complex128
if *ToComplex128(x) != x {
t.Fail()
}
}
func TestComplex64(t *testing.T) {
var x complex64
if *ToComplex64(x) != x {
t.Fail()
}
}
func TestError(t *testing.T) {
var x error
if *ToError(x) != x {
t.Fail()
}
}
func TestFloat32(t *testing.T) {
var x float32
if *ToFloat32(x) != x {
t.Fail()
}
}
func TestFloat64(t *testing.T) {
var x float64
if *ToFloat64(x) != x {
t.Fail()
}
}
func TestInt(t *testing.T) {
var x int
if *ToInt(x) != x {
t.Fail()
}
}
func TestInt16(t *testing.T) {
var x int16
if *ToInt16(x) != x {
t.Fail()
}
}
func TestInt32(t *testing.T) {
var x int32
if *ToInt32(x) != x {
t.Fail()
}
}
func TestInt64(t *testing.T) {
var x int64
if *ToInt64(x) != x {
t.Fail()
}
}
func TestInt8(t *testing.T) {
var x int8
if *ToInt8(x) != x {
t.Fail()
}
}
func TestRune(t *testing.T) {
var x rune
if *ToRune(x) != x {
t.Fail()
}
}
func TestString(t *testing.T) {
var x string
if *ToString(x) != x {
t.Fail()
}
}
func TestTime(t *testing.T) {
var x time.Time
if *ToTime(x) != x {
t.Fail()
}
}
func TestUint(t *testing.T) {
var x uint
if *ToUint(x) != x {
t.Fail()
}
}
func TestUint16(t *testing.T) {
var x uint16
if *ToUint16(x) != x {
t.Fail()
}
}
func TestUint32(t *testing.T) {
var x uint32
if *ToUint32(x) != x {
t.Fail()
}
}
func TestUint64(t *testing.T) {
var x uint64
if *ToUint64(x) != x {
t.Fail()
}
}
func TestUint8(t *testing.T) {
var x uint8
if *ToUint8(x) != x {
t.Fail()
}
}
func TestUintptr(t *testing.T) {
var x uintptr
if *ToUintptr(x) != x {
t.Fail()
}
}
func Example() {
const (
defaultName = "some name"
)
// Stuff contains optional fields.
type Stuff struct {
Name *string
Comment *string
Value *int64
Time *time.Time
}
b, _ := json.Marshal(&Stuff{
Name: ToString(defaultName), // can't say &defaultName
Comment: ToString("not yet"), // can't say &"not yet"
Value: ToInt64(42), // can't say &42 or &int64(42)
Time: ToTime(time.Date(2014, 6, 25, 12, 24, 40, 0, time.UTC)), // can't say &time.Date(…)
})
fmt.Printf("%s", b)
// Output: {"Name":"some name","Comment":"not yet","Value":42,"Time":"2014-06-25T12:24:40Z"}
}

View File

@@ -0,0 +1,4 @@
This is the official list of JsonConfigReader authors for copyright purposes.
* DisposaBoy `https://github.com/DisposaBoy`
* Steven Osborn `https://github.com/steve918`

View File

@@ -0,0 +1,7 @@
Copyright (c) 2012 The JsonConfigReader Authors
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.

View File

@@ -0,0 +1,36 @@
JsonConfigReader is a proxy for [golang's io.Reader](http://golang.org/pkg/io/#Reader) that strips line comments and trailing commas, allowing you to use json as a *reasonable* config format.
Comments start with `//` and continue to the end of the line.
If a trailing comma is in front of `]` or `}` it will be stripped as well.
Given `settings.json`
{
"key": "value", // k:v
// a list of numbers
"list": [1, 2, 3],
}
You can read it in as a *normal* json file:
package main
import (
"encoding/json"
"fmt"
"github.com/DisposaBoy/JsonConfigReader"
"os"
)
func main() {
var v interface{}
f, _ := os.Open("settings.json")
// wrap our reader before passing it to the json decoder
r := JsonConfigReader.New(f)
json.NewDecoder(r).Decode(&v)
fmt.Println(v)
}

View File

@@ -0,0 +1,94 @@
package JsonConfigReader
import (
"bytes"
"io"
)
type state struct {
r io.Reader
br *bytes.Reader
}
func isNL(c byte) bool {
return c == '\n' || c == '\r'
}
func isWS(c byte) bool {
return c == ' ' || c == '\t' || isNL(c)
}
func consumeComment(s []byte, i int) int {
if i < len(s) && s[i] == '/' {
s[i-1] = ' '
for ; i < len(s) && !isNL(s[i]); i += 1 {
s[i] = ' '
}
}
return i
}
func prep(r io.Reader) (s []byte, err error) {
buf := &bytes.Buffer{}
_, err = io.Copy(buf, r)
s = buf.Bytes()
if err != nil {
return
}
i := 0
for i < len(s) {
switch s[i] {
case '"':
i += 1
for i < len(s) {
if s[i] == '"' {
i += 1
break
} else if s[i] == '\\' {
i += 1
}
i += 1
}
case '/':
i = consumeComment(s, i+1)
case ',':
j := i
for {
i += 1
if i >= len(s) {
break
} else if s[i] == '}' || s[i] == ']' {
s[j] = ' '
break
} else if s[i] == '/' {
i = consumeComment(s, i+1)
} else if !isWS(s[i]) {
break
}
}
default:
i += 1
}
}
return
}
// Read acts as a proxy for the underlying reader and cleans p
// of comments and trailing commas preceeding ] and }
// comments are delimitted by // up until the end the line
func (st *state) Read(p []byte) (n int, err error) {
if st.br == nil {
var s []byte
if s, err = prep(st.r); err != nil {
return
}
st.br = bytes.NewReader(s)
}
return st.br.Read(p)
}
// New returns an io.Reader acting as proxy to r
func New(r io.Reader) io.Reader {
return &state{r: r}
}

View File

@@ -0,0 +1,66 @@
package JsonConfigReader
import (
"bytes"
"io"
"strings"
"testing"
)
var tests = map[string]string{
`{
// a
"x": "y", // b
"x": "y", // c
}`: `{
"x": "y",
"x": "y"
}`,
`// serve a directory
"l/test": [
{
"handler": "fs",
"dir": "../",
// "strip_prefix": "",
},
],`: `
"l/test": [
{
"handler": "fs",
"dir": "../"
}
],`,
`[1, 2, 3]`: `[1, 2, 3]`,
`[1, 2, 3, 4,]`: `[1, 2, 3, 4 ]`,
`{"x":1}//[1, 2, 3, 4,]`: `{"x":1} `,
`//////`: ` `,
`{}/ /..`: `{}/ /..`,
`{,}/ /..`: `{ }/ /..`,
`{,}//..`: `{ } `,
`{[],}`: `{[] }`,
`{[,}`: `{[ }`,
`[[",",],]`: `[["," ] ]`,
`[",\"",]`: `[",\"" ]`,
`[",\"\\\",]`: `[",\"\\\",]`,
`[",//"]`: `[",//"]`,
`[",//\"
"],`: `[",//\"
"],`,
}
func TestMain(t *testing.T) {
for a, b := range tests {
buf := &bytes.Buffer{}
io.Copy(buf, New(strings.NewReader(a)))
a = buf.String()
if a != b {
a = strings.Replace(a, " ", ".", -1)
b = strings.Replace(b, " ", ".", -1)
t.Errorf("reader failed to clean json: expected: `%s`, got `%s`", b, a)
}
}
}

View File

@@ -0,0 +1,10 @@
script:
- go build ./...
- go test ./...
- gofmt -l -s -w .
- git diff --exit-code
language: go
go:
- 1.7.1

14
vendor/github.com/awalterschulze/gographviz/AUTHORS generated vendored Normal file
View File

@@ -0,0 +1,14 @@
# This is the official list of GoGraphviz authors for copyright purposes.
# This file is distinct from the CONTRIBUTORS file, which
# lists people. For example, employees are listed in CONTRIBUTORS,
# but not in AUTHORS, because the employer holds the copyright.
# Names should be added to this file as one of
# Organization's name
# Individual's name <submission email address>
# Individual's name <submission email address> <email2> <emailN>
# Please keep the list sorted.
Vastech SA (PTY) LTD
Xavier Chassin <xavier.chassin@live.fr>

View File

@@ -0,0 +1 @@
Walter Schulze <awalterschulze@gmail.com>

46
vendor/github.com/awalterschulze/gographviz/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,46 @@
Copyright 2013 GoGraphviz Authors
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.
-------------------------------------------------------------------------------
Portions of gocc's source code has been derived from Go, and are covered by the
following license:
-------------------------------------------------------------------------------
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

34
vendor/github.com/awalterschulze/gographviz/Readme.md generated vendored Normal file
View File

@@ -0,0 +1,34 @@
Parses the Graphviz DOT language and creates an interface, in golang, with which to easily create new and manipulate existing graphs which can be written back to the DOT format.
This parser has been created using [gocc](http://code.google.com/p/gocc).
### Example (Parse and Edit) ###
```
graphAst, _ := parser.ParseString(`digraph G {}`)
graph := NewGraph()
Analyse(graphAst, graph)
graph.AddNode("G", "a", nil)
graph.AddNode("G", "b", nil)
graph.AddEdge("a", "b", true, nil)
output := graph.String()
```
### Documentation ###
The [godoc](https://godoc.org/github.com/awalterschulze/gographviz) includes some more examples.
### Installation ###
go get github.com/awalterschulze/gographviz
### Tests ###
[![Build Status](https://travis-ci.org/awalterschulze/gographviz.svg?branch=master)](https://travis-ci.org/awalterschulze/gographviz)
### Users ###
[aptly](https://github.com/smira/aptly) - Debian repository management tool
### Mentions ###
[Using Golang and GraphViz to Visualize Complex Grails Applications](http://ilikeorangutans.github.io/2014/05/03/using-golang-and-graphviz-to-visualize-complex-grails-applications/)

168
vendor/github.com/awalterschulze/gographviz/analyse.go generated vendored Normal file
View File

@@ -0,0 +1,168 @@
//Copyright 2013 GoGraphviz Authors
//
//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.
package gographviz
import (
"github.com/awalterschulze/gographviz/ast"
)
//Creates a Graph structure by analysing an Abstract Syntax Tree representing a parsed graph.
func NewAnalysedGraph(graph *ast.Graph) Interface {
g := NewGraph()
Analyse(graph, g)
return g
}
//Analyses an Abstract Syntax Tree representing a parsed graph into a newly created graph structure Interface.
func Analyse(graph *ast.Graph, g Interface) {
graph.Walk(&graphVisitor{g})
}
type nilVisitor struct {
}
func (this *nilVisitor) Visit(v ast.Elem) ast.Visitor {
return this
}
type graphVisitor struct {
g Interface
}
func (this *graphVisitor) Visit(v ast.Elem) ast.Visitor {
graph, ok := v.(*ast.Graph)
if !ok {
return this
}
this.g.SetStrict(graph.Strict)
this.g.SetDir(graph.Type == ast.DIGRAPH)
graphName := graph.Id.String()
this.g.SetName(graphName)
return newStmtVisitor(this.g, graphName)
}
func newStmtVisitor(g Interface, graphName string) *stmtVisitor {
return &stmtVisitor{g, graphName, make(Attrs), make(Attrs), make(Attrs)}
}
type stmtVisitor struct {
g Interface
graphName string
currentNodeAttrs Attrs
currentEdgeAttrs Attrs
currentGraphAttrs Attrs
}
func (this *stmtVisitor) Visit(v ast.Elem) ast.Visitor {
switch s := v.(type) {
case ast.NodeStmt:
return this.nodeStmt(s)
case ast.EdgeStmt:
return this.edgeStmt(s)
case ast.NodeAttrs:
return this.nodeAttrs(s)
case ast.EdgeAttrs:
return this.edgeAttrs(s)
case ast.GraphAttrs:
return this.graphAttrs(s)
case *ast.SubGraph:
return this.subGraph(s)
case *ast.Attr:
return this.attr(s)
case ast.AttrList:
return &nilVisitor{}
default:
//fmt.Fprintf(os.Stderr, "unknown stmt %T\n", v)
}
return this
}
func ammend(attrs Attrs, add Attrs) Attrs {
for key, value := range add {
if _, ok := attrs[key]; !ok {
attrs[key] = value
}
}
return attrs
}
func overwrite(attrs Attrs, overwrite Attrs) Attrs {
for key, value := range overwrite {
attrs[key] = value
}
return attrs
}
func (this *stmtVisitor) nodeStmt(stmt ast.NodeStmt) ast.Visitor {
attrs := Attrs(stmt.Attrs.GetMap())
attrs = ammend(attrs, this.currentNodeAttrs)
this.g.AddNode(this.graphName, stmt.NodeId.String(), attrs)
return &nilVisitor{}
}
func (this *stmtVisitor) edgeStmt(stmt ast.EdgeStmt) ast.Visitor {
attrs := stmt.Attrs.GetMap()
attrs = ammend(attrs, this.currentEdgeAttrs)
src := stmt.Source.GetId()
srcName := src.String()
if stmt.Source.IsNode() {
this.g.AddNode(this.graphName, srcName, this.currentNodeAttrs.Copy())
}
srcPort := stmt.Source.GetPort()
for i := range stmt.EdgeRHS {
directed := bool(stmt.EdgeRHS[i].Op)
dst := stmt.EdgeRHS[i].Destination.GetId()
dstName := dst.String()
if stmt.EdgeRHS[i].Destination.IsNode() {
this.g.AddNode(this.graphName, dstName, this.currentNodeAttrs.Copy())
}
dstPort := stmt.EdgeRHS[i].Destination.GetPort()
this.g.AddPortEdge(srcName, srcPort.String(), dstName, dstPort.String(), directed, attrs)
src = dst
srcPort = dstPort
srcName = dstName
}
return this
}
func (this *stmtVisitor) nodeAttrs(stmt ast.NodeAttrs) ast.Visitor {
this.currentNodeAttrs = overwrite(this.currentNodeAttrs, ast.AttrList(stmt).GetMap())
return &nilVisitor{}
}
func (this *stmtVisitor) edgeAttrs(stmt ast.EdgeAttrs) ast.Visitor {
this.currentEdgeAttrs = overwrite(this.currentEdgeAttrs, ast.AttrList(stmt).GetMap())
return &nilVisitor{}
}
func (this *stmtVisitor) graphAttrs(stmt ast.GraphAttrs) ast.Visitor {
attrs := ast.AttrList(stmt).GetMap()
for key, value := range attrs {
this.g.AddAttr(this.graphName, key, value)
}
this.currentGraphAttrs = overwrite(this.currentGraphAttrs, attrs)
return &nilVisitor{}
}
func (this *stmtVisitor) subGraph(stmt *ast.SubGraph) ast.Visitor {
subGraphName := stmt.Id.String()
this.g.AddSubGraph(this.graphName, subGraphName, this.currentGraphAttrs)
return newStmtVisitor(this.g, subGraphName)
}
func (this *stmtVisitor) attr(stmt *ast.Attr) ast.Visitor {
this.g.AddAttr(this.graphName, stmt.Field.String(), stmt.Value.String())
return this
}

View File

@@ -0,0 +1,318 @@
//Copyright 2013 GoGraphviz Authors
//
//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.
package gographviz
import (
"fmt"
"github.com/awalterschulze/gographviz/parser"
"io/ioutil"
"os"
"testing"
)
func (this *Nodes) String() string {
s := "Nodes:"
for i := range this.Nodes {
s += fmt.Sprintf("Node{%v}", this.Nodes[i])
}
return s + "\n"
}
func (this *Edges) String() string {
s := "Edges:"
for i := range this.Edges {
s += fmt.Sprintf("Edge{%v}", this.Edges[i])
}
return s + "\n"
}
func check(t *testing.T, err error) {
if err != nil {
t.Fatalf("%v", err)
}
}
func assert(t *testing.T, msg string, v1 interface{}, v2 interface{}) {
if v1 != v2 {
t.Fatalf("%v %v != %v", msg, v1, v2)
}
}
func anal(t *testing.T, input string) Interface {
t.Logf("Input: %v\n", input)
g, err := parser.ParseString(input)
check(t, err)
t.Logf("Parsed: %v\n", g)
ag := NewGraph()
Analyse(g, ag)
t.Logf("Analysed: %v\n", ag)
agstr := ag.String()
t.Logf("Written: %v\n", agstr)
g2, err := parser.ParseString(agstr)
check(t, err)
t.Logf("Parsed %v\n", g2)
ag2 := NewEscape()
Analyse(g2, ag2)
t.Logf("Analysed %v\n", ag2)
ag2str := ag2.String()
t.Logf("Written: %v\n", ag2str)
assert(t, "analysed", agstr, ag2str)
return ag2
}
func analfile(t *testing.T, filename string) Interface {
f, err := os.Open(filename)
check(t, err)
all, err := ioutil.ReadAll(f)
check(t, err)
return anal(t, string(all))
}
func analtest(t *testing.T, testname string) Interface {
return analfile(t, "./testdata/"+testname)
}
func TestHelloWorldString(t *testing.T) {
input := `digraph G {Hello->World}`
anal(t, input)
}
func TestHelloWorldFile(t *testing.T) {
analfile(t, "./testdata/helloworld.gv.txt")
}
func TestAttr(t *testing.T) {
anal(t,
"digraph finite_state { rankdir = LR }")
}
func TestString(t *testing.T) {
anal(t,
`digraph finite_state { rankdir = "LR" }`)
}
func TestAttrList(t *testing.T) {
anal(t, `
digraph { node [ shape = doublecircle ] }`)
}
func TestStringLit(t *testing.T) {
anal(t, `digraph finite_state_machine {
size= "8" ; }`)
}
func TestHashComments(t *testing.T) {
anal(t, `## bla \n
digraph G {Hello->World}`)
}
func TestIntLit(t *testing.T) {
anal(t, `graph G {
1 -- 30 [f=1];}`)
}
func TestFloat1(t *testing.T) {
anal(t, `digraph { bla = 2.0 }`)
}
func TestFloat2(t *testing.T) {
anal(t, `digraph { bla = .1 }`)
}
func TestNegative(t *testing.T) {
anal(t, `digraph { -2 -> -1 }`)
}
func TestUnderscore(t *testing.T) {
anal(t, `digraph { a_b = 1 }`)
}
func TestNonAscii(t *testing.T) {
anal(t, `digraph { label=T<>th }`)
}
func TestPorts(t *testing.T) {
anal(t, `digraph { "node6":f0 -> "node9":f1 }`)
}
func TestHtml(t *testing.T) {
anal(t, `digraph { a = <<table></table>> }`)
}
func TestIdWithKeyword(t *testing.T) {
anal(t, `digraph { edgeURL = "a" }`)
}
func TestSubGraph(t *testing.T) {
anal(t, `digraph { subgraph { a -> b } }`)
}
func TestImplicitSubGraph(t *testing.T) {
anal(t, `digraph { { a -> b } }`)
}
func TestEdges(t *testing.T) {
anal(t, `digraph { a0 -> a1 -> a2 -> a3 }`)
}
func TestEasyFsm1(t *testing.T) {
anal(t, `digraph finite_state_machine {
rankdir=LR;
size="8,5";
node [shape = circle];
LR_0 -> LR_2 [ label = "SS(B)" ];
LR_0 -> LR_1 [ label = "SS(S)" ];
LR_1 -> LR_3 [ label = "S($end)" ];
LR_2 -> LR_6 [ label = "SS(b)" ];
LR_2 -> LR_5 [ label = "SS(a)" ];
LR_2 -> LR_4 [ label = "S(A)" ];
LR_5 -> LR_7 [ label = "S(b)" ];
LR_5 -> LR_5 [ label = "S(a)" ];
LR_6 -> LR_6 [ label = "S(b)" ];
LR_6 -> LR_5 [ label = "S(a)" ];
LR_7 -> LR_8 [ label = "S(b)" ];
LR_7 -> LR_5 [ label = "S(a)" ];
LR_8 -> LR_6 [ label = "S(b)" ];
LR_8 -> LR_5 [ label = "S(a)" ];
}`)
}
//node [shape = doublecircle]; LR_0 LR_3 LR_4 LR_8; should be applied to the nodes
func TestEasyFsm2(t *testing.T) {
anal(t, `digraph finite_state_machine {
rankdir=LR;
size="8,5";
node [shape = doublecircle]; LR_0 LR_3 LR_4 LR_8;
node [shape = circle];
LR_0 -> LR_2 [ label = "SS(B)" ];
LR_0 -> LR_1 [ label = "SS(S)" ];
LR_1 -> LR_3 [ label = "S($end)" ];
LR_2 -> LR_6 [ label = "SS(b)" ];
LR_2 -> LR_5 [ label = "SS(a)" ];
LR_2 -> LR_4 [ label = "S(A)" ];
LR_5 -> LR_7 [ label = "S(b)" ];
LR_5 -> LR_5 [ label = "S(a)" ];
LR_6 -> LR_6 [ label = "S(b)" ];
LR_6 -> LR_5 [ label = "S(a)" ];
LR_7 -> LR_8 [ label = "S(b)" ];
LR_7 -> LR_5 [ label = "S(a)" ];
LR_8 -> LR_6 [ label = "S(b)" ];
LR_8 -> LR_5 [ label = "S(a)" ];
}`)
}
func TestEmptyAttrList(t *testing.T) {
anal(t, `digraph g { edge [ ] }`)
}
func TestHelloWorld(t *testing.T) {
analtest(t, "helloworld.gv.txt")
}
func TestCluster(t *testing.T) {
analtest(t, "cluster.gv.txt")
}
func TestPsg(t *testing.T) {
analtest(t, "psg.gv.txt")
}
func TestTransparency(t *testing.T) {
analtest(t, "transparency.gv.txt")
}
func TestCrazy(t *testing.T) {
analtest(t, "crazy.gv.txt")
}
func TestKennedyanc(t *testing.T) {
analtest(t, "kennedyanc.gv.txt")
}
func TestRoot(t *testing.T) {
analtest(t, "root.gv.txt")
}
func TestTwpoi(t *testing.T) {
analtest(t, "twopi.gv.txt")
}
func TestDataStruct(t *testing.T) {
analtest(t, "datastruct.gv.txt")
}
func TestLionShare(t *testing.T) {
analtest(t, "lion_share.gv.txt")
}
func TestSdh(t *testing.T) {
analtest(t, "sdh.gv.txt")
}
func TestUnix(t *testing.T) {
analtest(t, "unix.gv.txt")
}
func TestEr(t *testing.T) {
analtest(t, "er.gv.txt")
}
func TestNerworkMapTwopi(t *testing.T) {
analtest(t, "networkmap_twopi.gv.txt")
}
func TestSibling(t *testing.T) {
analtest(t, "siblings.gv.txt")
}
func TestWorld(t *testing.T) {
analtest(t, "world.gv.txt")
}
func TestFdpclust(t *testing.T) {
analtest(t, "fdpclust.gv.txt")
}
func TestPhilo(t *testing.T) {
analtest(t, "philo.gv.txt")
}
func TestSoftmaint(t *testing.T) {
analtest(t, "softmaint.gv.txt")
}
func TestFsm(t *testing.T) {
analtest(t, "fsm.gv.txt")
}
func TestProcess(t *testing.T) {
analtest(t, "process.gv.txt")
}
func TestSwitchGv(t *testing.T) {
analtest(t, "switch.gv.txt")
}
func TestGd19942007(t *testing.T) {
analtest(t, "gd_1994_2007.gv.txt")
}
func TestProfile(t *testing.T) {
analtest(t, "profile.gv.txt")
}
func TestTrafficLights(t *testing.T) {
analtest(t, "traffic_lights.gv.txt")
}

690
vendor/github.com/awalterschulze/gographviz/ast/ast.go generated vendored Normal file
View File

@@ -0,0 +1,690 @@
//Copyright 2013 GoGraphviz Authors
//
//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.
//Abstract Syntax Tree representing the DOT grammar
package ast
import (
"errors"
"fmt"
"github.com/awalterschulze/gographviz/token"
"math/rand"
"sort"
"strings"
)
var (
r = rand.New(rand.NewSource(1234))
)
type Visitor interface {
Visit(e Elem) Visitor
}
type Elem interface {
String() string
}
type Walkable interface {
Walk(v Visitor)
}
type Bool bool
const (
FALSE = Bool(false)
TRUE = Bool(true)
)
func (this Bool) String() string {
switch this {
case false:
return "false"
case true:
return "true"
}
panic("unreachable")
}
func (this Bool) Walk(v Visitor) {
if v == nil {
return
}
v.Visit(this)
}
type GraphType bool
const (
GRAPH = GraphType(false)
DIGRAPH = GraphType(true)
)
func (this GraphType) String() string {
switch this {
case false:
return "graph"
case true:
return "digraph"
}
panic("unreachable")
}
func (this GraphType) Walk(v Visitor) {
if v == nil {
return
}
v.Visit(this)
}
type Graph struct {
Type GraphType
Strict bool
Id Id
StmtList StmtList
}
func NewGraph(t, strict, id, l Elem) (*Graph, error) {
g := &Graph{Type: t.(GraphType), Strict: bool(strict.(Bool)), Id: Id("")}
if id != nil {
g.Id = id.(Id)
}
if l != nil {
g.StmtList = l.(StmtList)
}
return g, nil
}
func (this *Graph) String() string {
s := this.Type.String() + " " + this.Id.String() + " {\n"
if this.StmtList != nil {
s += this.StmtList.String()
}
s += "\n}\n"
return s
}
func (this *Graph) Walk(v Visitor) {
if v == nil {
return
}
v = v.Visit(this)
this.Type.Walk(v)
this.Id.Walk(v)
this.StmtList.Walk(v)
}
type StmtList []Stmt
func NewStmtList(s Elem) (StmtList, error) {
ss := make(StmtList, 1)
ss[0] = s.(Stmt)
return ss, nil
}
func AppendStmtList(ss, s Elem) (StmtList, error) {
this := ss.(StmtList)
this = append(this, s.(Stmt))
return this, nil
}
func (this StmtList) String() string {
if len(this) == 0 {
return ""
}
s := ""
for i := 0; i < len(this); i++ {
ss := this[i].String()
if len(ss) > 0 {
s += "\t" + ss + ";\n"
}
}
return s
}
func (this StmtList) Walk(v Visitor) {
if v == nil {
return
}
v = v.Visit(this)
for i := range this {
this[i].Walk(v)
}
}
type Stmt interface {
Elem
Walkable
isStmt()
}
func (this NodeStmt) isStmt() {}
func (this EdgeStmt) isStmt() {}
func (this EdgeAttrs) isStmt() {}
func (this NodeAttrs) isStmt() {}
func (this GraphAttrs) isStmt() {}
func (this *SubGraph) isStmt() {}
func (this *Attr) isStmt() {}
type SubGraph struct {
Id Id
StmtList StmtList
}
func NewSubGraph(id, l Elem) (*SubGraph, error) {
g := &SubGraph{Id: Id(fmt.Sprintf("anon%d", r.Int63()))}
if id != nil {
if len(id.(Id)) > 0 {
g.Id = id.(Id)
}
}
if l != nil {
g.StmtList = l.(StmtList)
}
return g, nil
}
func (this *SubGraph) GetId() Id {
return this.Id
}
func (this *SubGraph) GetPort() Port {
port, err := NewPort(nil, nil)
if err != nil {
panic(err)
}
return port
}
func (this *SubGraph) String() string {
gName := this.Id.String()
if strings.HasPrefix(gName, "anon") {
gName = ""
}
s := "subgraph " + this.Id.String() + " {\n"
if this.StmtList != nil {
s += this.StmtList.String()
}
s += "\n}\n"
return s
}
func (this *SubGraph) Walk(v Visitor) {
if v == nil {
return
}
v = v.Visit(this)
this.Id.Walk(v)
this.StmtList.Walk(v)
}
type EdgeAttrs AttrList
func NewEdgeAttrs(a Elem) (EdgeAttrs, error) {
return EdgeAttrs(a.(AttrList)), nil
}
func (this EdgeAttrs) String() string {
s := AttrList(this).String()
if len(s) == 0 {
return ""
}
return `edge ` + s
}
func (this EdgeAttrs) Walk(v Visitor) {
if v == nil {
return
}
v = v.Visit(this)
for i := range this {
this[i].Walk(v)
}
}
type NodeAttrs AttrList
func NewNodeAttrs(a Elem) (NodeAttrs, error) {
return NodeAttrs(a.(AttrList)), nil
}
func (this NodeAttrs) String() string {
s := AttrList(this).String()
if len(s) == 0 {
return ""
}
return `node ` + s
}
func (this NodeAttrs) Walk(v Visitor) {
if v == nil {
return
}
v = v.Visit(this)
for i := range this {
this[i].Walk(v)
}
}
type GraphAttrs AttrList
func NewGraphAttrs(a Elem) (GraphAttrs, error) {
return GraphAttrs(a.(AttrList)), nil
}
func (this GraphAttrs) String() string {
s := AttrList(this).String()
if len(s) == 0 {
return ""
}
return `graph ` + s
}
func (this GraphAttrs) Walk(v Visitor) {
if v == nil {
return
}
v = v.Visit(this)
for i := range this {
this[i].Walk(v)
}
}
type AttrList []AList
func NewAttrList(a Elem) (AttrList, error) {
as := make(AttrList, 0)
if a != nil {
as = append(as, a.(AList))
}
return as, nil
}
func AppendAttrList(as, a Elem) (AttrList, error) {
this := as.(AttrList)
if a == nil {
return this, nil
}
this = append(this, a.(AList))
return this, nil
}
func (this AttrList) String() string {
s := ""
for _, alist := range this {
ss := alist.String()
if len(ss) > 0 {
s += "[ " + ss + " ] "
}
}
if len(s) == 0 {
return ""
}
return s
}
func (this AttrList) Walk(v Visitor) {
if v == nil {
return
}
v = v.Visit(this)
for i := range this {
this[i].Walk(v)
}
}
func PutMap(attrmap map[string]string) AttrList {
attrlist := make(AttrList, 1)
attrlist[0] = make(AList, 0)
keys := make([]string, 0, len(attrmap))
for key := range attrmap {
keys = append(keys, key)
}
sort.Strings(keys)
for _, name := range keys {
value := attrmap[name]
attrlist[0] = append(attrlist[0], &Attr{Id(name), Id(value)})
}
return attrlist
}
func (this AttrList) GetMap() map[string]string {
attrs := make(map[string]string)
for _, alist := range this {
for _, attr := range alist {
attrs[attr.Field.String()] = attr.Value.String()
}
}
return attrs
}
type AList []*Attr
func NewAList(a Elem) (AList, error) {
as := make(AList, 1)
as[0] = a.(*Attr)
return as, nil
}
func AppendAList(as, a Elem) (AList, error) {
this := as.(AList)
attr := a.(*Attr)
this = append(this, attr)
return this, nil
}
func (this AList) String() string {
if len(this) == 0 {
return ""
}
str := this[0].String()
for i := 1; i < len(this); i++ {
str += `, ` + this[i].String()
}
return str
}
func (this AList) Walk(v Visitor) {
v = v.Visit(this)
for i := range this {
this[i].Walk(v)
}
}
type Attr struct {
Field Id
Value Id
}
func NewAttr(f, v Elem) (*Attr, error) {
a := &Attr{Field: f.(Id)}
a.Value = Id("true")
if v != nil {
ok := false
a.Value, ok = v.(Id)
if !ok {
return nil, errors.New(fmt.Sprintf("value = %v", v))
}
}
return a, nil
}
func (this *Attr) String() string {
return this.Field.String() + `=` + this.Value.String()
}
func (this *Attr) Walk(v Visitor) {
if v == nil {
return
}
v = v.Visit(this)
this.Field.Walk(v)
this.Value.Walk(v)
}
type Location interface {
Elem
Walkable
isLocation()
GetId() Id
GetPort() Port
IsNode() bool
}
func (this *NodeId) isLocation() {}
func (this *NodeId) IsNode() bool { return true }
func (this *SubGraph) isLocation() {}
func (this *SubGraph) IsNode() bool { return false }
type EdgeStmt struct {
Source Location
EdgeRHS EdgeRHS
Attrs AttrList
}
func NewEdgeStmt(id, e, attrs Elem) (*EdgeStmt, error) {
var a AttrList = nil
var err error = nil
if attrs == nil {
a, err = NewAttrList(nil)
if err != nil {
return nil, err
}
} else {
a = attrs.(AttrList)
}
return &EdgeStmt{id.(Location), e.(EdgeRHS), a}, nil
}
func (this EdgeStmt) String() string {
return strings.TrimSpace(this.Source.String() + this.EdgeRHS.String() + this.Attrs.String())
}
func (this EdgeStmt) Walk(v Visitor) {
if v == nil {
return
}
v = v.Visit(this)
this.Source.Walk(v)
this.EdgeRHS.Walk(v)
this.Attrs.Walk(v)
}
type EdgeRHS []*EdgeRH
func NewEdgeRHS(op, id Elem) (EdgeRHS, error) {
return EdgeRHS{&EdgeRH{op.(EdgeOp), id.(Location)}}, nil
}
func AppendEdgeRHS(e, op, id Elem) (EdgeRHS, error) {
erhs := e.(EdgeRHS)
erhs = append(erhs, &EdgeRH{op.(EdgeOp), id.(Location)})
return erhs, nil
}
func (this EdgeRHS) String() string {
s := ""
for i := range this {
s += this[i].String()
}
return strings.TrimSpace(s)
}
func (this EdgeRHS) Walk(v Visitor) {
if v == nil {
return
}
v = v.Visit(this)
for i := range this {
this[i].Walk(v)
}
}
type EdgeRH struct {
Op EdgeOp
Destination Location
}
func (this *EdgeRH) String() string {
return strings.TrimSpace(this.Op.String() + this.Destination.String())
}
func (this *EdgeRH) Walk(v Visitor) {
if v == nil {
return
}
v = v.Visit(this)
this.Op.Walk(v)
this.Destination.Walk(v)
}
type NodeStmt struct {
NodeId *NodeId
Attrs AttrList
}
func NewNodeStmt(id, attrs Elem) (*NodeStmt, error) {
nid := id.(*NodeId)
var a AttrList = nil
var err error = nil
if attrs == nil {
a, err = NewAttrList(nil)
if err != nil {
return nil, err
}
} else {
a = attrs.(AttrList)
}
return &NodeStmt{nid, a}, nil
}
func (this NodeStmt) String() string {
return strings.TrimSpace(this.NodeId.String() + ` ` + this.Attrs.String())
}
func (this NodeStmt) Walk(v Visitor) {
if v == nil {
return
}
v = v.Visit(this)
this.NodeId.Walk(v)
this.Attrs.Walk(v)
}
type EdgeOp bool
const (
DIRECTED EdgeOp = true
UNDIRECTED EdgeOp = false
)
func (this EdgeOp) String() string {
switch this {
case DIRECTED:
return "->"
case UNDIRECTED:
return "--"
}
panic("unreachable")
}
func (this EdgeOp) Walk(v Visitor) {
if v == nil {
return
}
v.Visit(this)
}
type NodeId struct {
Id Id
Port Port
}
func NewNodeId(id Elem, port Elem) (*NodeId, error) {
if port == nil {
return &NodeId{id.(Id), Port{"", ""}}, nil
}
return &NodeId{id.(Id), port.(Port)}, nil
}
func MakeNodeId(id string, port string) *NodeId {
p := Port{"", ""}
if len(port) > 0 {
ps := strings.Split(port, ":")
p.Id1 = Id(ps[1])
if len(ps) > 2 {
p.Id2 = Id(ps[2])
}
}
return &NodeId{Id(id), p}
}
func (this *NodeId) String() string {
return this.Id.String() + this.Port.String()
}
func (this *NodeId) GetId() Id {
return this.Id
}
func (this *NodeId) GetPort() Port {
return this.Port
}
func (this *NodeId) Walk(v Visitor) {
if v == nil {
return
}
v = v.Visit(this)
this.Id.Walk(v)
this.Port.Walk(v)
}
//TODO semantic analysis should decide which Id is an Id and which is a Compass Point
type Port struct {
Id1 Id
Id2 Id
}
func NewPort(id1, id2 Elem) (Port, error) {
port := Port{Id(""), Id("")}
if id1 != nil {
port.Id1 = id1.(Id)
}
if id2 != nil {
port.Id2 = id2.(Id)
}
return port, nil
}
func (this Port) String() string {
if len(this.Id1) == 0 {
return ""
}
s := ":" + this.Id1.String()
if len(this.Id2) > 0 {
s += ":" + this.Id2.String()
}
return s
}
func (this Port) Walk(v Visitor) {
if v == nil {
return
}
v = v.Visit(this)
this.Id1.Walk(v)
this.Id2.Walk(v)
}
type Id string
func NewId(id Elem) (Id, error) {
if id == nil {
return Id(""), nil
}
id_lit := string(id.(*token.Token).Lit)
return Id(id_lit), nil
}
func (this Id) String() string {
return string(this)
}
func (this Id) Walk(v Visitor) {
if v == nil {
return
}
v.Visit(this)
}

71
vendor/github.com/awalterschulze/gographviz/attrs.go generated vendored Normal file
View File

@@ -0,0 +1,71 @@
//Copyright 2013 GoGraphviz Authors
//
//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.
package gographviz
import (
"fmt"
"os"
"sort"
)
//Represents attributes for an Edge, Node or Graph.
type Attrs map[string]string
//Creates an empty Attributes type.
func NewAttrs() Attrs {
return make(Attrs)
}
//Adds an attribute name and value.
func (this Attrs) Add(field string, value string) {
prev, ok := this[field]
if ok {
fmt.Fprintf(os.Stderr, "WARNING: overwriting field %v value %v, with value %v\n", field, prev, value)
}
this[field] = value
}
//Adds the attributes into this Attrs type overwriting duplicates.
func (this Attrs) Extend(more Attrs) {
for key, value := range more {
this.Add(key, value)
}
}
//Only adds the missing attributes to this Attrs type.
func (this Attrs) Ammend(more Attrs) {
for key, value := range more {
if _, ok := this[key]; !ok {
this.Add(key, value)
}
}
}
func (this Attrs) SortedNames() []string {
keys := make([]string, 0)
for key := range this {
keys = append(keys, key)
}
sort.Strings(keys)
return keys
}
func (this Attrs) Copy() Attrs {
attrs := make(Attrs)
for k, v := range this {
attrs[k] = v
}
return attrs
}

View File

@@ -0,0 +1,42 @@
package gographviz
import (
"github.com/awalterschulze/gographviz/ast"
"github.com/awalterschulze/gographviz/parser"
"testing"
)
type bugSubGraphWorldVisitor struct {
t *testing.T
found bool
}
func (this *bugSubGraphWorldVisitor) Visit(v ast.Elem) ast.Visitor {
edge, ok := v.(ast.EdgeStmt)
if !ok {
return this
}
if edge.Source.GetId().String() != "2" {
return this
}
dst := edge.EdgeRHS[0].Destination
if _, ok := dst.(*ast.SubGraph); !ok {
this.t.Fatalf("2 -> Not SubGraph")
} else {
this.found = true
}
return this
}
func TestBugSubGraphWorld(t *testing.T) {
g := analtest(t, "world.gv.txt")
st, err := parser.ParseString(g.String())
check(t, err)
s := &bugSubGraphWorldVisitor{
t: t,
}
st.Walk(s)
if !s.found {
t.Fatalf("2 -> SubGraph not found")
}
}

209
vendor/github.com/awalterschulze/gographviz/dot.bnf generated vendored Normal file
View File

@@ -0,0 +1,209 @@
//Copyright 2013 GoGraphviz Authors
//
//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.
//This bnf has been derived from http://www.graphviz.org/content/dot-language
//The rules have been copied and are shown in the comments, with their derived bnf rules below.
//graph : [ strict ] (graph | digraph) [ ID ] '{' stmt_list '}'
DotGraph
: Graph "{" "}" << ast.NewGraph(ast.GRAPH, ast.FALSE, nil, nil) >>
| Strict Graph "{" "}" << ast.NewGraph(ast.GRAPH, ast.TRUE, nil, nil) >>
| Graph Id "{" "}" << ast.NewGraph(ast.GRAPH, ast.FALSE, $1, nil) >>
| Strict Graph Id "{" "}" << ast.NewGraph(ast.GRAPH, ast.TRUE, $2, nil) >>
| Graph "{" StmtList "}" << ast.NewGraph(ast.GRAPH, ast.FALSE, nil, $2) >>
| Graph Id "{" StmtList "}" << ast.NewGraph(ast.GRAPH, ast.FALSE, $1, $3) >>
| Strict Graph "{" StmtList "}" << ast.NewGraph(ast.GRAPH, ast.TRUE, nil, $3) >>
| Strict Graph Id "{" StmtList "}" << ast.NewGraph(ast.GRAPH, ast.TRUE, $2, $4) >>
| Digraph "{" "}" << ast.NewGraph(ast.DIGRAPH, ast.FALSE, nil, nil) >>
| Strict Digraph "{" "}" << ast.NewGraph(ast.DIGRAPH, ast.TRUE, nil, nil) >>
| Digraph Id "{" "}" << ast.NewGraph(ast.DIGRAPH, ast.FALSE, $1, nil) >>
| Strict Digraph Id "{" "}" << ast.NewGraph(ast.DIGRAPH, ast.TRUE, $2, nil) >>
| Digraph "{" StmtList "}" << ast.NewGraph(ast.DIGRAPH, ast.FALSE, nil, $2) >>
| Digraph Id "{" StmtList "}" << ast.NewGraph(ast.DIGRAPH, ast.FALSE, $1, $3) >>
| Strict Digraph "{" StmtList "}" << ast.NewGraph(ast.DIGRAPH, ast.TRUE, nil, $3) >>
| Strict Digraph Id "{" StmtList "}" << ast.NewGraph(ast.DIGRAPH, ast.TRUE, $2, $4) >>
;
//stmt_list : [ stmt [ ';' ] [ stmt_list ] ]
StmtList
: Stmt1 << ast.NewStmtList($0) >>
| StmtList Stmt1 << ast.AppendStmtList($0, $1) >>
;
Stmt1
: Stmt << $0, nil >>
| Stmt ";" << $0, nil >>
;
//stmt : node_stmt | edge_stmt | attr_stmt | (ID '=' ID) | subgraph
Stmt
: Id "=" Id << ast.NewAttr($0, $2) >>
| NodeStmt << $0, nil >>
| EdgeStmt << $0, nil >>
| AttrStmt << $0, nil >>
| SubGraphStmt << $0, nil >>
;
//attr_stmt : (graph | node | edge) attr_list
AttrStmt
: Graph AttrList << ast.NewGraphAttrs($1) >>
| Node AttrList << ast.NewNodeAttrs($1) >>
| Edge AttrList << ast.NewEdgeAttrs($1) >>
;
//attr_list : '[' [ a_list ] ']' [ attr_list ]
AttrList
: "[" "]" << ast.NewAttrList(nil) >>
| "[" AList "]" << ast.NewAttrList($1) >>
| AttrList "[" "]" << ast.AppendAttrList($0, nil) >>
| AttrList "[" AList "]" << ast.AppendAttrList($0, $2) >>
;
//a_list : ID [ '=' ID ] [ ',' ] [ a_list ]
AList
: Attr << ast.NewAList($0) >>
| AList Attr << ast.AppendAList($0, $1) >>
| AList "," Attr << ast.AppendAList($0, $2) >>
;
//An a_list clause of the form ID is equivalent to ID=true.
Attr
: Id << ast.NewAttr($0, nil) >>
| Id "=" Id << ast.NewAttr($0, $2) >>
;
//edge_stmt : (node_id | subgraph) edgeRHS [ attr_list ]
EdgeStmt
: NodeId EdgeRHS << ast.NewEdgeStmt($0, $1, nil) >>
| NodeId EdgeRHS AttrList << ast.NewEdgeStmt($0, $1, $2) >>
| SubGraphStmt EdgeRHS << ast.NewEdgeStmt($0, $1, nil) >>
| SubGraphStmt EdgeRHS AttrList << ast.NewEdgeStmt($0, $1, $2) >>
;
//edgeRHS : edgeop (node_id | subgraph) [ edgeRHS ]
EdgeRHS
: EdgeOp NodeId << ast.NewEdgeRHS($0, $1) >>
| EdgeOp SubGraphStmt << ast.NewEdgeRHS($0, $1) >>
| EdgeRHS EdgeOp NodeId << ast.AppendEdgeRHS($0, $1, $2) >>
| EdgeRHS EdgeOp SubGraphStmt << ast.AppendEdgeRHS($0, $1, $2) >>
;
//node_stmt : node_id [ attr_list ]
NodeStmt
: NodeId << ast.NewNodeStmt($0, nil) >>
| NodeId AttrList << ast.NewNodeStmt($0, $1) >>
;
//node_id : ID [ port ]
NodeId
: Id << ast.NewNodeId($0, nil) >>
| Id Port << ast.NewNodeId($0, $1) >>
;
//compass_pt : (n | ne | e | se | s | sw | w | nw | c | _)
//Note also that the allowed compass point values are not keywords,
//so these strings can be used elsewhere as ordinary identifiers and,
//conversely, the parser will actually accept any identifier.
//port : ':' ID [ ':' compass_pt ]
// | ':' compass_pt
Port
: ":" Id << ast.NewPort($1, nil) >>
| ":" Id ":" Id << ast.NewPort($1, $3) >>
;
//subgraph : [ subgraph [ ID ] ] '{' stmt_list '}'
SubGraphStmt
: "{" StmtList "}" << ast.NewSubGraph(nil, $1) >>
| Subgraph "{" StmtList "}" << ast.NewSubGraph(nil, $2) >>
| Subgraph Id "{" StmtList "}" << ast.NewSubGraph($1, $3) >>
;
//An edgeop is -> in directed graphs and -- in undirected graphs.
EdgeOp
: "->" << ast.DIRECTED, nil >>
| "--" << ast.UNDIRECTED, nil >>
;
//The keywords node, edge, graph, digraph, subgraph, and strict are case-independent.
Graph
: "graph" << $0, nil >>
| "Graph" << $0, nil >>
| "GRAPH" << $0, nil >>
;
Strict
: "strict" << $0, nil >>
| "Strict" << $0, nil >>
| "STRICT" << $0, nil >>
;
Digraph
: "digraph" << $0, nil >>
| "Digraph" << $0, nil >>
| "DiGraph" << $0, nil >>
| "DIGRAPH" << $0, nil >>
;
Node
: "node" << $0, nil >>
| "Node" << $0, nil >>
| "NODE" << $0, nil >>
;
Edge
: "edge" << $0, nil >>
| "Edge" << $0, nil >>
| "EDGE" << $0, nil >>
;
Subgraph
: "subgraph" << $0, nil >>
| "Subgraph" << $0, nil >>
| "SubGraph" << $0, nil >>
| "SUBGRAPH" << $0, nil >>
;
// An ID is one of the following:
// Any string of alphabetic ([a-zA-Z'200-'377]) characters, underscores ('_') or digits ([0-9]), not beginning with a digit; //CHECK 200-377
// a numeral [-]?(.[0-9]+ | [0-9]+(.[0-9]*)? );
// any double-quoted string ("...") possibly containing escaped quotes ('")1; //TODO
// an HTML string (<...>).
// An ID is just a string; the lack of quote characters in the first two forms is just for simplicity.
// There is no semantic difference between abc_2 and "abc_2", or between 2.34 and "2.34".
// Obviously, to use a keyword as an ID, it must be quoted. Note that, in HTML strings, angle brackets must occur in matched pairs, and unescaped newlines are allowed.
// In addition, the content must be legal XML, so that the special XML escape sequences for ", &, <, and > may be necessary in order to embed these characters in attribute values or raw text.
// Both quoted strings and HTML strings are scanned as a unit, so any embedded comments will be treated as part of the strings.
Id
: id << ast.NewId($0) >>
| string_lit << ast.NewId($0) >>
| int_lit << ast.NewId($0) >>
| float_lit << ast.NewId($0) >>
| html_lit << ast.NewId($0) >>
;
//The language supports C++-style comments: /* */ and //.
//In addition, a line beginning with a '#' character is considered a line output from a C preprocessor (e.g., # 34 to indicate line 34 ) and discarded.
//TODO (if dot file is not parsable, it might be because of these points)
//Semicolons aid readability but are not required except in the rare case that a named subgraph with no body immediately preceeds an anonymous subgraph,
//since the precedence rules cause this sequence to be parsed as a subgraph with a heading and a body. Also, any amount of whitespace may be inserted between terminals.
//TODO
//As another aid for readability, dot allows single logical lines to span multiple physical lines using the standard C convention of a backslash immediately preceding a newline character.
//In addition, double-quoted strings can be concatenated using a '+' operator. As HTML strings can contain newline characters, they do not support the concatenation operator.
//TODO
//Note there are still 3 sections on the webpage which have not been included (Subgraphs and Clusters, Lexical and Semantic Notes, and Character Encodings)

119
vendor/github.com/awalterschulze/gographviz/edges.go generated vendored Normal file
View File

@@ -0,0 +1,119 @@
//Copyright 2013 GoGraphviz Authors
//
//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.
package gographviz
import (
"sort"
)
//Represents an Edge.
type Edge struct {
Src string
SrcPort string
Dst string
DstPort string
Dir bool
Attrs Attrs
}
//Represents a set of Edges.
type Edges struct {
SrcToDsts map[string]map[string][]*Edge
DstToSrcs map[string]map[string][]*Edge
Edges []*Edge
}
//Creates a blank set of Edges.
func NewEdges() *Edges {
return &Edges{make(map[string]map[string][]*Edge), make(map[string]map[string][]*Edge), make([]*Edge, 0)}
}
//Adds an Edge to the set of Edges.
func (this *Edges) Add(edge *Edge) {
if _, ok := this.SrcToDsts[edge.Src]; !ok {
this.SrcToDsts[edge.Src] = make(map[string][]*Edge)
}
if _, ok := this.SrcToDsts[edge.Src][edge.Dst]; !ok {
this.SrcToDsts[edge.Src][edge.Dst] = make([]*Edge, 0)
}
this.SrcToDsts[edge.Src][edge.Dst] = append(this.SrcToDsts[edge.Src][edge.Dst], edge)
if _, ok := this.DstToSrcs[edge.Dst]; !ok {
this.DstToSrcs[edge.Dst] = make(map[string][]*Edge)
}
if _, ok := this.DstToSrcs[edge.Dst][edge.Src]; !ok {
this.DstToSrcs[edge.Dst][edge.Src] = make([]*Edge, 0)
}
this.DstToSrcs[edge.Dst][edge.Src] = append(this.DstToSrcs[edge.Dst][edge.Src], edge)
this.Edges = append(this.Edges, edge)
}
//Returns a sorted list of Edges.
func (this Edges) Sorted() []*Edge {
es := make(edgeSorter, len(this.Edges))
copy(es, this.Edges)
sort.Sort(es)
return es
}
type edgeSorter []*Edge
func (es edgeSorter) Len() int { return len(es) }
func (es edgeSorter) Swap(i, j int) { es[i], es[j] = es[j], es[i] }
func (es edgeSorter) Less(i, j int) bool {
if es[i].Src < es[j].Src {
return true
} else if es[i].Src > es[j].Src {
return false
}
if es[i].Dst < es[j].Dst {
return true
} else if es[i].Dst > es[j].Dst {
return false
}
if es[i].SrcPort < es[j].SrcPort {
return true
} else if es[i].SrcPort > es[j].SrcPort {
return false
}
if es[i].DstPort < es[j].DstPort {
return true
} else if es[i].DstPort > es[j].DstPort {
return false
}
if es[i].Dir != es[j].Dir {
return es[i].Dir
}
attrs := es[i].Attrs.Copy()
for k, v := range es[j].Attrs {
attrs[k] = v
}
for _, k := range attrs.SortedNames() {
if es[i].Attrs[k] < es[j].Attrs[k] {
return true
} else if es[i].Attrs[k] > es[j].Attrs[k] {
return false
}
}
return false
}

View File

@@ -0,0 +1,177 @@
//Copyright 2013 GoGraphviz Authors
//
//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.
package gographviz
import (
"reflect"
"testing"
)
func TestEdges_Sorted(t *testing.T) {
var tts = map[string]struct {
edges []*Edge
expected []*Edge
}{
"empty": {
edges: []*Edge{},
expected: []*Edge{},
},
"one edge": {
edges: []*Edge{
{Src: "0", Dst: "1", Attrs: map[string]string{"label": "abc"}},
},
expected: []*Edge{
{Src: "0", Dst: "1", Attrs: map[string]string{"label": "abc"}},
},
},
"two non parallel edges": {
edges: []*Edge{
{Src: "0", Dst: "2", Attrs: map[string]string{"label": "hello"}},
{Src: "0", Dst: "1", Attrs: map[string]string{"label": "abc"}},
},
expected: []*Edge{
{Src: "0", Dst: "1", Attrs: map[string]string{"label": "abc"}},
{Src: "0", Dst: "2", Attrs: map[string]string{"label": "hello"}},
},
},
"two parallel edges": {
edges: []*Edge{
{Src: "0", Dst: "1", Attrs: map[string]string{"label": "hello"}},
{Src: "0", Dst: "1", Attrs: map[string]string{"label": "abc"}},
},
expected: []*Edge{
{Src: "0", Dst: "1", Attrs: map[string]string{"label": "abc"}},
{Src: "0", Dst: "1", Attrs: map[string]string{"label": "hello"}},
},
},
"two parallel edges - one without label": {
edges: []*Edge{
{Src: "0", Dst: "1", Attrs: map[string]string{"label": "abc"}},
{Src: "0", Dst: "1"},
},
expected: []*Edge{
{Src: "0", Dst: "1"},
{Src: "0", Dst: "1", Attrs: map[string]string{"label": "abc"}},
},
},
"several non parallel edges": {
edges: []*Edge{
{Src: "0", Dst: "2", Attrs: map[string]string{"label": "hello"}},
{Src: "1", Dst: "1", Attrs: map[string]string{"label": "world"}},
{Src: "0", Dst: "1", Attrs: map[string]string{"label": "abc"}},
{Src: "1", Dst: "0", Attrs: map[string]string{"label": "golang"}},
},
expected: []*Edge{
{Src: "0", Dst: "1", Attrs: map[string]string{"label": "abc"}},
{Src: "0", Dst: "2", Attrs: map[string]string{"label": "hello"}},
{Src: "1", Dst: "0", Attrs: map[string]string{"label": "golang"}},
{Src: "1", Dst: "1", Attrs: map[string]string{"label": "world"}},
},
},
"several with parallel edges": {
edges: []*Edge{
{Src: "0", Dst: "2", Attrs: map[string]string{"label": "hello"}},
{Src: "0", Dst: "1", Attrs: map[string]string{"label": "cba"}},
{Src: "1", Dst: "1", Attrs: map[string]string{"label": "world"}},
{Src: "0", Dst: "1", Attrs: map[string]string{"label": "abc"}},
{Src: "1", Dst: "0", Attrs: map[string]string{"label": "gopher"}},
{Src: "1", Dst: "0", Attrs: map[string]string{"label": "golang"}},
},
expected: []*Edge{
{Src: "0", Dst: "1", Attrs: map[string]string{"label": "abc"}},
{Src: "0", Dst: "1", Attrs: map[string]string{"label": "cba"}},
{Src: "0", Dst: "2", Attrs: map[string]string{"label": "hello"}},
{Src: "1", Dst: "0", Attrs: map[string]string{"label": "golang"}},
{Src: "1", Dst: "0", Attrs: map[string]string{"label": "gopher"}},
{Src: "1", Dst: "1", Attrs: map[string]string{"label": "world"}},
},
},
"edges with ports": {
edges: []*Edge{
{Src: "0", Dst: "1", SrcPort: "a", DstPort: "b"},
{Src: "0", Dst: "1", SrcPort: "a", DstPort: "a"},
{Src: "0", Dst: "1", SrcPort: "b", DstPort: "a"},
},
expected: []*Edge{
{Src: "0", Dst: "1", SrcPort: "a", DstPort: "a"},
{Src: "0", Dst: "1", SrcPort: "a", DstPort: "b"},
{Src: "0", Dst: "1", SrcPort: "b", DstPort: "a"},
},
},
"directed edges before non directed edges": {
edges: []*Edge{
{Src: "0", Dst: "1", Dir: false},
{Src: "0", Dst: "1", Dir: true},
},
expected: []*Edge{
{Src: "0", Dst: "1", Dir: true},
{Src: "0", Dst: "1", Dir: false},
},
},
"the theory of everything": {
edges: []*Edge{
{Src: "0", Dst: "1", Attrs: map[string]string{"label": "cba"}},
{Src: "1", Dst: "0", SrcPort: "a", Dir: false, Attrs: map[string]string{"label": "gopher"}},
{Src: "0", Dst: "1", Attrs: map[string]string{"label": "abc"}},
{Src: "0", Dst: "2", Attrs: map[string]string{"label": "hello"}},
{Src: "1", Dst: "0", Attrs: map[string]string{"label": "gopher"}},
{Src: "1", Dst: "0", Attrs: map[string]string{"label": "golang"}},
{Src: "1", Dst: "0", SrcPort: "b", Attrs: map[string]string{"label": "gopher"}},
{Src: "1", Dst: "0", SrcPort: "a", DstPort: "b", Attrs: map[string]string{"label": "golang"}},
{Src: "1", Dst: "1", Attrs: map[string]string{"comment": "test", "label": "world"}},
{Src: "1", Dst: "0", SrcPort: "a", DstPort: "a", Attrs: map[string]string{"label": "golang"}},
{Src: "1", Dst: "0", SrcPort: "a", Attrs: map[string]string{"label": "golang"}},
{Src: "1", Dst: "0", SrcPort: "b", Dir: false, Attrs: map[string]string{"label": "gopher"}},
{Src: "1", Dst: "1", Attrs: map[string]string{"label": "world"}},
{Src: "1", Dst: "0", SrcPort: "a", DstPort: "b", Dir: true, Attrs: map[string]string{"label": "golang"}},
{Src: "1", Dst: "1", Attrs: map[string]string{"comment": "test", "label": "hello"}},
{Src: "1", Dst: "0", SrcPort: "a", Dir: true, Attrs: map[string]string{"label": "golang"}},
{Src: "1", Dst: "0", SrcPort: "a", DstPort: "b", Dir: true, Attrs: map[string]string{"label": "graphviz"}},
},
expected: []*Edge{
{Src: "0", Dst: "1", Attrs: map[string]string{"label": "abc"}},
{Src: "0", Dst: "1", Attrs: map[string]string{"label": "cba"}},
{Src: "0", Dst: "2", Attrs: map[string]string{"label": "hello"}},
{Src: "1", Dst: "0", Attrs: map[string]string{"label": "golang"}},
{Src: "1", Dst: "0", Attrs: map[string]string{"label": "gopher"}},
{Src: "1", Dst: "0", SrcPort: "a", Dir: true, Attrs: map[string]string{"label": "golang"}},
{Src: "1", Dst: "0", SrcPort: "a", Attrs: map[string]string{"label": "golang"}},
{Src: "1", Dst: "0", SrcPort: "a", Dir: false, Attrs: map[string]string{"label": "gopher"}},
{Src: "1", Dst: "0", SrcPort: "a", DstPort: "a", Attrs: map[string]string{"label": "golang"}},
{Src: "1", Dst: "0", SrcPort: "a", DstPort: "b", Dir: true, Attrs: map[string]string{"label": "golang"}},
{Src: "1", Dst: "0", SrcPort: "a", DstPort: "b", Dir: true, Attrs: map[string]string{"label": "graphviz"}},
{Src: "1", Dst: "0", SrcPort: "a", DstPort: "b", Attrs: map[string]string{"label": "golang"}},
{Src: "1", Dst: "0", SrcPort: "b", Dir: false, Attrs: map[string]string{"label": "gopher"}},
{Src: "1", Dst: "0", SrcPort: "b", Attrs: map[string]string{"label": "gopher"}},
{Src: "1", Dst: "1", Attrs: map[string]string{"label": "world"}},
{Src: "1", Dst: "1", Attrs: map[string]string{"comment": "test", "label": "hello"}},
{Src: "1", Dst: "1", Attrs: map[string]string{"comment": "test", "label": "world"}},
},
},
}
for name, tt := range tts {
edges := NewEdges()
for _, e := range tt.edges {
edges.Add(e)
}
s := edges.Sorted()
if !reflect.DeepEqual(tt.expected, s) {
t.Errorf("%s - Sorted invalid: expected %v got %v", name, tt.expected, s)
} else if !reflect.DeepEqual(edges.Edges, tt.edges) {
t.Errorf("%s - Sorted should not have changed original order: expected %v got %v", name, tt.edges, edges.Edges)
}
}
}

185
vendor/github.com/awalterschulze/gographviz/escape.go generated vendored Normal file
View File

@@ -0,0 +1,185 @@
//Copyright 2013 GoGraphviz Authors
//
//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.
package gographviz
import (
"fmt"
"github.com/awalterschulze/gographviz/scanner"
"github.com/awalterschulze/gographviz/token"
"strings"
"text/template"
"unicode"
)
type Escape struct {
*Graph
}
//Returns a graph which will try to escape some strings when required
func NewEscape() *Escape {
return &Escape{NewGraph()}
}
func isHtml(s string) bool {
if len(s) == 0 {
return false
}
ss := strings.TrimSpace(s)
if ss[0] != '<' {
return false
}
count := 0
for _, c := range ss {
if c == '<' {
count += 1
}
if c == '>' {
count -= 1
}
}
if count == 0 {
return true
}
return false
}
func isLetter(ch rune) bool {
return 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' || ch == '_' ||
ch >= 0x80 && unicode.IsLetter(ch) && ch != 'ε'
}
func isId(s string) bool {
i := 0
pos := false
for _, c := range s {
if i == 0 {
if !isLetter(c) {
return false
}
pos = true
}
if unicode.IsSpace(c) {
return false
}
if c == '-' {
return false
}
i++
}
return pos
}
func isDigit(ch rune) bool {
return '0' <= ch && ch <= '9' || ch >= 0x80 && unicode.IsDigit(ch)
}
func isNumber(s string) bool {
state := 0
for _, c := range s {
if state == 0 {
if isDigit(c) || c == '.' {
state = 2
} else if c == '-' {
state = 1
} else {
return false
}
} else if state == 1 {
if isDigit(c) || c == '.' {
state = 2
}
} else if c != '.' && !isDigit(c) {
return false
}
}
return (state == 2)
}
func isStringLit(s string) bool {
lex := &scanner.Scanner{}
lex.Init([]byte(s), token.DOTTokens)
tok, _ := lex.Scan()
if tok.Type != token.DOTTokens.Type("string_lit") {
return false
}
tok, _ = lex.Scan()
if tok.Type != token.EOF {
return false
}
return true
}
func esc(s string) string {
if len(s) == 0 {
return s
}
if isHtml(s) {
return s
}
ss := strings.TrimSpace(s)
if ss[0] == '<' {
return fmt.Sprintf("\"%s\"", strings.Replace(s, "\"", "\\\"", -1))
}
if isId(s) {
return s
}
if isNumber(s) {
return s
}
if isStringLit(s) {
return s
}
return fmt.Sprintf("\"%s\"", template.HTMLEscapeString(s))
}
func escAttrs(attrs map[string]string) map[string]string {
newAttrs := make(map[string]string)
for k, v := range attrs {
newAttrs[esc(k)] = esc(v)
}
return newAttrs
}
func (this *Escape) SetName(name string) {
this.Graph.SetName(esc(name))
}
func (this *Escape) AddPortEdge(src, srcPort, dst, dstPort string, directed bool, attrs map[string]string) {
this.Graph.AddPortEdge(esc(src), srcPort, esc(dst), dstPort, directed, escAttrs(attrs))
}
func (this *Escape) AddEdge(src, dst string, directed bool, attrs map[string]string) {
this.AddPortEdge(src, "", dst, "", directed, attrs)
}
func (this *Escape) AddNode(parentGraph string, name string, attrs map[string]string) {
this.Graph.AddNode(esc(parentGraph), esc(name), escAttrs(attrs))
}
func (this *Escape) AddAttr(parentGraph string, field, value string) {
this.Graph.AddAttr(esc(parentGraph), esc(field), esc(value))
}
func (this *Escape) AddSubGraph(parentGraph string, name string, attrs map[string]string) {
this.Graph.AddSubGraph(esc(parentGraph), esc(name), escAttrs(attrs))
}
func (this *Escape) IsNode(name string) bool {
return this.Graph.IsNode(esc(name))
}
func (this *Escape) IsSubGraph(name string) bool {
return this.Graph.IsSubGraph(esc(name))
}

View File

@@ -0,0 +1,47 @@
//Copyright 2013 GoGraphviz Authors
//
//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.
package gographviz
import (
"strings"
"testing"
)
func TestEscape(t *testing.T) {
g := NewEscape()
g.SetName("asdf adsf")
g.SetDir(true)
g.AddNode("asdf asdf", "kasdf99 99", map[string]string{
"<asfd": "1",
})
g.AddNode("asdf asdf", "7", map[string]string{
"<asfd": "1",
})
g.AddNode("asdf asdf", "a << b", nil)
g.AddEdge("kasdf99 99", "7", true, nil)
s := g.String()
if !strings.HasPrefix(s, `digraph "asdf adsf" {
"kasdf99 99"->7;
"a &lt;&lt; b";
"kasdf99 99" [ "<asfd"=1 ];
7 [ "<asfd"=1 ];
}`) {
t.Fatalf("%s", s)
}
if !g.IsNode("a << b") {
t.Fatalf("should be a node")
}
}

View File

@@ -0,0 +1,160 @@
//Copyright 2013 GoGraphviz Authors
//
//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.
package gographviz
import (
"fmt"
"strconv"
)
func ExampleRead() {
g, err := Read([]byte(`digraph G {Hello->World}`))
if err != nil {
panic(err)
}
s := g.String()
fmt.Println(s)
// Output: digraph G {
// Hello->World;
// Hello;
// World;
//
//}
}
func ExampleNewGraph() {
g := NewGraph()
g.SetName("G")
g.SetDir(true)
g.AddNode("G", "Hello", nil)
g.AddNode("G", "World", nil)
g.AddEdge("Hello", "World", true, nil)
s := g.String()
fmt.Println(s)
// Output: digraph G {
// Hello->World;
// Hello;
// World;
//
//}
}
type MyOwnGraphStructure struct {
weights map[int]map[int]int
max int
}
func NewMyOwnGraphStructure() *MyOwnGraphStructure {
return &MyOwnGraphStructure{
make(map[int]map[int]int),
0,
}
}
func (this *MyOwnGraphStructure) SetStrict(strict bool) {}
func (this *MyOwnGraphStructure) SetDir(directed bool) {}
func (this *MyOwnGraphStructure) SetName(name string) {}
func (this *MyOwnGraphStructure) AddPortEdge(src, srcPort, dst, dstPort string, directed bool, attrs map[string]string) {
srci, err := strconv.Atoi(src)
if err != nil {
return
}
dsti, err := strconv.Atoi(dst)
if err != nil {
return
}
ai, err := strconv.Atoi(attrs["label"])
if err != nil {
return
}
if _, ok := this.weights[srci]; !ok {
this.weights[srci] = make(map[int]int)
}
this.weights[srci][dsti] = ai
if srci > this.max {
this.max = srci
}
if dsti > this.max {
this.max = dsti
}
}
func (this *MyOwnGraphStructure) AddEdge(src, dst string, directed bool, attrs map[string]string) {
this.AddPortEdge(src, "", dst, "", directed, attrs)
}
func (this *MyOwnGraphStructure) AddNode(parentGraph string, name string, attrs map[string]string) {}
func (this *MyOwnGraphStructure) AddAttr(parentGraph string, field, value string) {}
func (this *MyOwnGraphStructure) AddSubGraph(parentGraph string, name string, attrs map[string]string) {
}
func (this *MyOwnGraphStructure) String() string { return "" }
//An Example of how to parse into your own simpler graph structure and output it back to graphviz.
//This example reads in only numbers and outputs a matrix graph.
func ExampleMyOwnGraphStructure() {
name := "matrix"
parsed, err := Parse([]byte(`
digraph G {
1 -> 2 [ label = 5 ];
4 -> 2 [ label = 1 ];
4 -> 1 [ label = 2 ];
1 -> 1 [ label = 0 ];
}
`))
if err != nil {
panic(err)
}
mine := NewMyOwnGraphStructure()
Analyse(parsed, mine)
output := NewGraph()
output.SetName(name)
output.SetDir(true)
for i := 1; i <= mine.max; i++ {
output.AddNode(name, fmt.Sprintf("%v", i), nil)
if _, ok := mine.weights[i]; !ok {
mine.weights[i] = make(map[int]int)
}
}
for i := 1; i <= mine.max; i++ {
for j := 1; j <= mine.max; j++ {
output.AddEdge(fmt.Sprintf("%v", i), fmt.Sprintf("%v", j), true, map[string]string{"label": fmt.Sprintf("%v", mine.weights[i][j])})
}
}
s := output.String()
fmt.Println(s)
// Output: digraph matrix {
// 1->1[ label=0 ];
// 1->2[ label=5 ];
// 1->3[ label=0 ];
// 1->4[ label=0 ];
// 2->1[ label=0 ];
// 2->2[ label=0 ];
// 2->3[ label=0 ];
// 2->4[ label=0 ];
// 3->1[ label=0 ];
// 3->2[ label=0 ];
// 3->3[ label=0 ];
// 3->4[ label=0 ];
// 4->1[ label=2 ];
// 4->2[ label=1 ];
// 4->3[ label=0 ];
// 4->4[ label=0 ];
// 1;
// 2;
// 3;
// 4;
//
//}
}

4
vendor/github.com/awalterschulze/gographviz/gen.sh generated vendored Executable file
View File

@@ -0,0 +1,4 @@
gocc -o ../ -p . dot.bnf
cp ./parser/parser.temp ./parser/parser.go
gofix parser/tables.go
gofix token/token.go

View File

@@ -0,0 +1,53 @@
//Copyright 2013 GoGraphviz Authors
//
//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.
//Package gographviz provides parsing for the DOT grammar into
//an abstract syntax tree representing a graph,
//analysis of the abstract syntax tree into a more usable structure,
//and writing back of this structure into the DOT format.
package gographviz
import (
"github.com/awalterschulze/gographviz/ast"
"github.com/awalterschulze/gographviz/parser"
)
var _ Interface = NewGraph()
//Implementing this interface allows you to parse the graph into your own structure.
type Interface interface {
SetStrict(strict bool)
SetDir(directed bool)
SetName(name string)
AddPortEdge(src, srcPort, dst, dstPort string, directed bool, attrs map[string]string)
AddEdge(src, dst string, directed bool, attrs map[string]string)
AddNode(parentGraph string, name string, attrs map[string]string)
AddAttr(parentGraph string, field, value string)
AddSubGraph(parentGraph string, name string, attrs map[string]string)
String() string
}
//Parses the buffer into a abstract syntax tree representing the graph.
func Parse(buf []byte) (*ast.Graph, error) {
return parser.ParseBytes(buf)
}
//Parses and creates a new Graph from the data.
func Read(buf []byte) (Interface, error) {
st, err := Parse(buf)
if err != nil {
return nil, err
}
return NewAnalysedGraph(st), nil
}

113
vendor/github.com/awalterschulze/gographviz/graph.go generated vendored Normal file
View File

@@ -0,0 +1,113 @@
//Copyright 2013 GoGraphviz Authors
//
//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.
package gographviz
//The analysed representation of the Graph parsed from the DOT format.
type Graph struct {
Attrs Attrs
Name string
Directed bool
Strict bool
Nodes *Nodes
Edges *Edges
SubGraphs *SubGraphs
Relations *Relations
}
//Creates a new empty graph, ready to be populated.
func NewGraph() *Graph {
return &Graph{
Attrs: make(Attrs),
Name: "",
Directed: false,
Strict: false,
Nodes: NewNodes(),
Edges: NewEdges(),
SubGraphs: NewSubGraphs(),
Relations: NewRelations(),
}
}
//If the graph is strict then multiple edges are not allowed between the same pairs of nodes,
//see dot man page.
func (this *Graph) SetStrict(strict bool) {
this.Strict = strict
}
//Sets whether the graph is directed (true) or undirected (false).
func (this *Graph) SetDir(dir bool) {
this.Directed = dir
}
//Sets the graph name.
func (this *Graph) SetName(name string) {
this.Name = name
}
//Adds an edge to the graph from node src to node dst.
//srcPort and dstPort are the port the node ports, leave as empty strings if it is not required.
//This does not imply the adding of missing nodes.
func (this *Graph) AddPortEdge(src, srcPort, dst, dstPort string, directed bool, attrs map[string]string) {
this.Edges.Add(&Edge{src, srcPort, dst, dstPort, directed, attrs})
}
//Adds an edge to the graph from node src to node dst.
//This does not imply the adding of missing nodes.
//If directed is set to true then SetDir(true) must also be called or there will be a syntax error in the output.
func (this *Graph) AddEdge(src, dst string, directed bool, attrs map[string]string) {
this.AddPortEdge(src, "", dst, "", directed, attrs)
}
//Adds a node to a graph/subgraph.
//If not subgraph exists use the name of the main graph.
//This does not imply the adding of a missing subgraph.
func (this *Graph) AddNode(parentGraph string, name string, attrs map[string]string) {
this.Nodes.Add(&Node{name, attrs})
this.Relations.Add(parentGraph, name)
}
func (this *Graph) getAttrs(graphName string) Attrs {
if this.Name == graphName {
return this.Attrs
}
g, ok := this.SubGraphs.SubGraphs[graphName]
if !ok {
panic("graph or subgraph " + graphName + " does not exist")
}
return g.Attrs
}
//Adds an attribute to a graph/subgraph.
func (this *Graph) AddAttr(parentGraph string, field string, value string) {
this.getAttrs(parentGraph).Add(field, value)
}
//Adds a subgraph to a graph/subgraph.
func (this *Graph) AddSubGraph(parentGraph string, name string, attrs map[string]string) {
this.SubGraphs.Add(name)
for key, value := range attrs {
this.AddAttr(name, key, value)
}
}
func (this *Graph) IsNode(name string) bool {
_, ok := this.Nodes.Lookup[name]
return ok
}
func (this *Graph) IsSubGraph(name string) bool {
_, ok := this.SubGraphs.SubGraphs[name]
return ok
}

61
vendor/github.com/awalterschulze/gographviz/nodes.go generated vendored Normal file
View File

@@ -0,0 +1,61 @@
//Copyright 2013 GoGraphviz Authors
//
//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.
package gographviz
import (
"sort"
)
//Represents a Node.
type Node struct {
Name string
Attrs Attrs
}
//Represents a set of Nodes.
type Nodes struct {
Lookup map[string]*Node
Nodes []*Node
}
//Creates a new set of Nodes.
func NewNodes() *Nodes {
return &Nodes{make(map[string]*Node), make([]*Node, 0)}
}
//Adds a Node to the set of Nodes, ammending the attributes of an already existing node.
func (this *Nodes) Add(node *Node) {
n, ok := this.Lookup[node.Name]
if ok {
n.Attrs.Ammend(node.Attrs)
return
}
this.Lookup[node.Name] = node
this.Nodes = append(this.Nodes, node)
}
//Returns a sorted list of nodes.
func (this Nodes) Sorted() []*Node {
keys := make([]string, 0, len(this.Lookup))
for key := range this.Lookup {
keys = append(keys, key)
}
sort.Strings(keys)
nodes := make([]*Node, len(keys))
for i := range keys {
nodes[i] = this.Lookup[keys[i]]
}
return nodes
}

View File

@@ -0,0 +1,69 @@
//Copyright 2013 GoGraphviz Authors
//
//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.
//A parser for the DOT grammar.
package parser
import (
"fmt"
"github.com/awalterschulze/gographviz/ast"
"github.com/awalterschulze/gographviz/scanner"
"github.com/awalterschulze/gographviz/token"
"io"
"io/ioutil"
"os"
)
//Parses a DOT string and outputs the
//abstract syntax tree representing the graph.
func ParseString(dotString string) (*ast.Graph, error) {
return ParseBytes([]byte(dotString))
}
//Parses the bytes representing a DOT string
//and outputs the abstract syntax tree representing the graph.
func ParseBytes(dotBytes []byte) (*ast.Graph, error) {
lex := &scanner.Scanner{}
lex.Init(dotBytes, token.DOTTokens)
parser := NewParser(ActionTable, GotoTable, ProductionsTable, token.DOTTokens)
st, err := parser.Parse(lex)
if err != nil {
return nil, err
}
g, ok := st.(*ast.Graph)
if !ok {
panic(fmt.Sprintf("Parser did not return an *ast.Graph, but rather a %T", st))
}
return g, err
}
//Parses a reader which contains a DOT string
//and outputs the abstract syntax tree representing the graph.
func Parse(r io.Reader) (*ast.Graph, error) {
bytes, err := ioutil.ReadAll(r)
if err != nil {
return nil, err
}
return ParseBytes(bytes)
}
//Parses a file which contains a DOT string
//and outputs the abstract syntax tree representing the graph.
func ParseFile(filename string) (*ast.Graph, error) {
f, err := os.Open(filename)
if err != nil {
return nil, err
}
return Parse(f)
}

View File

@@ -0,0 +1,200 @@
//Copyright 2013 GoGraphviz Authors
//
//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.
package parser
import (
"errors"
"strconv"
)
import "github.com/awalterschulze/gographviz/token"
type (
ActionTab []ActionRow
ActionRow map[token.Type]Action
)
func (R ActionRow) String() string {
s := ""
for t, a := range R {
s += strconv.Itoa(int(t)) + " : " + a.String() + "\n"
}
return s
}
type (
Accept int
Shift State
Reduce int
Action interface {
Act()
String() string
}
)
func (this Accept) Act() {}
func (this Shift) Act() {}
func (this Reduce) Act() {}
func (this Accept) String() string { return "Accept(0)" }
func (this Shift) String() string { return "Shift(" + strconv.Itoa(int(this)) + ")" }
func (this Reduce) String() string { return "Reduce(" + strconv.Itoa(int(this)) + ")" }
type (
GotoTab []GotoRow
GotoRow map[NT]State
State int
NT string
)
type (
ProdTab []ProdTabEntry
ProdTabEntry struct {
String string
Head NT
NumSymbols int
ReduceFunc func([]Attrib) (Attrib, error)
}
Attrib interface {
String() string
}
)
/*** Stack ***/
type stack struct {
state []State
attrib []Attrib
}
const INITIAL_STACK_SIZE = 100
func NewStack() *stack {
return &stack{state: make([]State, 0, INITIAL_STACK_SIZE),
attrib: make([]Attrib, 0, INITIAL_STACK_SIZE),
}
}
func (this *stack) Push(s State, a Attrib) {
this.state = append(this.state, s)
this.attrib = append(this.attrib, a)
}
func (this *stack) Top() State {
return this.state[len(this.state)-1]
}
func (this *stack) PopN(items int) []Attrib {
lo, hi := len(this.state)-items, len(this.state)
attrib := this.attrib[lo:hi]
this.state = this.state[:lo]
this.attrib = this.attrib[:lo]
return attrib
}
func (S *stack) String() string {
res := "stack:\n"
for i, st := range S.state {
res += "\t" + strconv.Itoa(i) + ": " + strconv.Itoa(int(st))
res += " , "
if S.attrib[i] == nil {
res += "nil"
} else {
res += S.attrib[i].String()
}
res += "\n"
}
return res
}
/*** Parser ***/
type Parser struct {
actTab ActionTab
gotoTab GotoTab
prodTab ProdTab
stack *stack
nextToken *token.Token
pos token.Position
tokenMap *token.TokenMap
}
type Scanner interface {
Scan() (*token.Token, token.Position)
}
func NewParser(act ActionTab, gto GotoTab, prod ProdTab, tm *token.TokenMap) *Parser {
p := &Parser{actTab: act, gotoTab: gto, prodTab: prod, stack: NewStack(), tokenMap: tm}
p.stack.Push(0, nil) //TODO: which attribute should be pushed here?
return p
}
func (P *Parser) Error(err error) error {
errmsg := "Error: " + P.TokString(P.nextToken) + " @ " + P.pos.String()
if err != nil {
errmsg += " " + err.Error()
} else {
errmsg += ", expected one of: "
actRow := P.actTab[P.stack.Top()]
i := 0
for t := range actRow {
errmsg += P.tokenMap.TokenString(t)
if i < len(actRow)-1 {
errmsg += " "
}
i++
}
}
return errors.New(errmsg)
}
func (P *Parser) TokString(tok *token.Token) string {
msg := P.tokenMap.TokenString(tok.Type) + "(" + strconv.Itoa(int(tok.Type)) + ")"
msg += " " + string(tok.Lit)
return msg
}
func (this *Parser) Parse(scanner Scanner) (res interface{}, err error) {
this.nextToken, this.pos = scanner.Scan()
for acc := false; !acc; {
action, ok := this.actTab[this.stack.Top()][this.nextToken.Type]
if !ok {
return nil, this.Error(nil)
}
switch act := action.(type) {
case Accept:
res = this.stack.PopN(1)[0]
acc = true
case Shift:
this.stack.Push(State(act), this.nextToken)
this.nextToken, this.pos = scanner.Scan()
case Reduce:
prod := this.prodTab[int(act)]
attrib, err := prod.ReduceFunc(this.stack.PopN(prod.NumSymbols))
if err != nil {
return nil, this.Error(err)
} else {
this.stack.Push(this.gotoTab[this.stack.Top()][prod.Head], attrib)
}
default:
panic("unknown action")
}
}
return res, nil
}

View File

@@ -0,0 +1,200 @@
//Copyright 2013 GoGraphviz Authors
//
//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.
package parser
import (
"errors"
"strconv"
)
import "github.com/awalterschulze/gographviz/token"
type (
ActionTab []ActionRow
ActionRow map[token.Type]Action
)
func (R ActionRow) String() string {
s := ""
for t, a := range R {
s += strconv.Itoa(int(t)) + " : " + a.String() + "\n"
}
return s
}
type (
Accept int
Shift State
Reduce int
Action interface {
Act()
String() string
}
)
func (this Accept) Act() {}
func (this Shift) Act() {}
func (this Reduce) Act() {}
func (this Accept) String() string { return "Accept(0)" }
func (this Shift) String() string { return "Shift(" + strconv.Itoa(int(this)) + ")" }
func (this Reduce) String() string { return "Reduce(" + strconv.Itoa(int(this)) + ")" }
type (
GotoTab []GotoRow
GotoRow map[NT]State
State int
NT string
)
type (
ProdTab []ProdTabEntry
ProdTabEntry struct {
String string
Head NT
NumSymbols int
ReduceFunc func([]Attrib) (Attrib, error)
}
Attrib interface {
String() string
}
)
/*** Stack ***/
type stack struct {
state []State
attrib []Attrib
}
const INITIAL_STACK_SIZE = 100
func NewStack() *stack {
return &stack{state: make([]State, 0, INITIAL_STACK_SIZE),
attrib: make([]Attrib, 0, INITIAL_STACK_SIZE),
}
}
func (this *stack) Push(s State, a Attrib) {
this.state = append(this.state, s)
this.attrib = append(this.attrib, a)
}
func (this *stack) Top() State {
return this.state[len(this.state)-1]
}
func (this *stack) PopN(items int) []Attrib {
lo, hi := len(this.state)-items, len(this.state)
attrib := this.attrib[lo:hi]
this.state = this.state[:lo]
this.attrib = this.attrib[:lo]
return attrib
}
func (S *stack) String() string {
res := "stack:\n"
for i, st := range S.state {
res += "\t" + strconv.Itoa(i) + ": " + strconv.Itoa(int(st))
res += " , "
if S.attrib[i] == nil {
res += "nil"
} else {
res += S.attrib[i].String()
}
res += "\n"
}
return res
}
/*** Parser ***/
type Parser struct {
actTab ActionTab
gotoTab GotoTab
prodTab ProdTab
stack *stack
nextToken *token.Token
pos token.Position
tokenMap *token.TokenMap
}
type Scanner interface {
Scan() (*token.Token, token.Position)
}
func NewParser(act ActionTab, gto GotoTab, prod ProdTab, tm *token.TokenMap) *Parser {
p := &Parser{actTab: act, gotoTab: gto, prodTab: prod, stack: NewStack(), tokenMap: tm}
p.stack.Push(0, nil) //TODO: which attribute should be pushed here?
return p
}
func (P *Parser) Error(err error) error {
errmsg := "Error: " + P.TokString(P.nextToken) + " @ " + P.pos.String()
if err != nil {
errmsg += " " + err.Error()
} else {
errmsg += ", expected one of: "
actRow := P.actTab[P.stack.Top()]
i := 0
for t := range actRow {
errmsg += P.tokenMap.TokenString(t)
if i < len(actRow)-1 {
errmsg += " "
}
i++
}
}
return errors.New(errmsg)
}
func (P *Parser) TokString(tok *token.Token) string {
msg := P.tokenMap.TokenString(tok.Type) + "(" + strconv.Itoa(int(tok.Type)) + ")"
msg += " " + string(tok.Lit)
return msg
}
func (this *Parser) Parse(scanner Scanner) (res interface{}, err error) {
this.nextToken, this.pos = scanner.Scan()
for acc := false; !acc; {
action, ok := this.actTab[this.stack.Top()][this.nextToken.Type]
if !ok {
return nil, this.Error(nil)
}
switch act := action.(type) {
case Accept:
res = this.stack.PopN(1)[0]
acc = true
case Shift:
this.stack.Push(State(act), this.nextToken)
this.nextToken, this.pos = scanner.Scan()
case Reduce:
prod := this.prodTab[int(act)]
attrib, err := prod.ReduceFunc(this.stack.PopN(prod.NumSymbols))
if err != nil {
return nil, this.Error(err)
} else {
this.stack.Push(this.gotoTab[this.stack.Top()][prod.Head], attrib)
}
default:
panic("unknown action")
}
}
return res, nil
}

View File

@@ -0,0 +1,293 @@
//Copyright 2013 GoGraphviz Authors
//
//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.
package parser
import (
"fmt"
"github.com/awalterschulze/gographviz/ast"
"io/ioutil"
"testing"
)
func check(t *testing.T, err error) {
if err != nil {
t.Fatalf("%v", err)
}
}
func assert(t *testing.T, msg string, v1 interface{}, v2 interface{}) {
if v1 != v2 {
t.Fatalf("%v\n%v\n!=\n%v", msg, v1, v2)
}
}
func parseTest(t *testing.T, filename string) {
localFilename := "../testdata/" + filename
s, err := ioutil.ReadFile(localFilename)
check(t, err)
t.Logf("Input String = %v", string(s))
g, err := ParseFile(localFilename)
t.Logf("First Parse = %v", g)
check(t, err)
gstr := g.String()
g2, err := ParseString(gstr)
t.Logf("Second Parse = %v", g2)
check(t, err)
gstr2 := g2.String()
assert(t, "output strings", gstr, gstr2)
}
func parseStringTest(t *testing.T, s string) {
t.Logf("Input String = %v", s)
g, err := ParseString(s)
t.Logf("First Parse = %v", g)
check(t, err)
gstr := g.String()
g2, err := ParseString(gstr)
t.Logf("Second Parse = %v", g2)
check(t, err)
gstr2 := g2.String()
assert(t, "output strings", gstr, gstr2)
}
func TestHelloWorldString(t *testing.T) {
input := `digraph G {Hello->World}`
g, err := ParseString(input)
check(t, err)
fmt.Printf("%#v", g)
}
func TestHelloWorldFile(t *testing.T) {
g, err := ParseFile("../testdata/helloworld.gv.txt")
check(t, err)
fmt.Printf("%#v", g)
}
func TestAttr(t *testing.T) {
parseStringTest(t,
"digraph finite_state { rankdir = LR }")
}
func TestString(t *testing.T) {
parseStringTest(t,
`digraph finite_state { rankdir = "LR" }`)
}
func TestAttrList(t *testing.T) {
parseStringTest(t, `
digraph { node [ shape = doublecircle ] }`)
}
func TestStringLit(t *testing.T) {
parseStringTest(t, `digraph finite_state_machine {
size= "8" ; }`)
}
func TestHashComments(t *testing.T) {
parseStringTest(t, `## bla \n
digraph G {Hello->World}`)
}
func TestIntLit(t *testing.T) {
parseStringTest(t, `graph G {
1 -- 30 [f=1];}`)
}
func TestFloat1(t *testing.T) {
parseStringTest(t, `digraph { bla = 2.0 }`)
}
func TestFloat2(t *testing.T) {
parseStringTest(t, `digraph { bla = .1 }`)
}
func TestNegative(t *testing.T) {
parseStringTest(t, `digraph { -2 -> -1 }`)
}
func TestUnderscore(t *testing.T) {
parseStringTest(t, `digraph { a_b = 1 }`)
}
func TestNonAscii(t *testing.T) {
parseStringTest(t, `digraph { label=T<>th }`)
}
func TestPorts(t *testing.T) {
parseStringTest(t, `digraph { "node6":f0 -> "node9":f1 }`)
}
func TestHtml(t *testing.T) {
parseStringTest(t, `digraph { a = <<table></table>> }`)
}
func TestIdWithKeyword(t *testing.T) {
parseStringTest(t, `digraph { edgeURL = "a" }`)
}
func TestSubGraph(t *testing.T) {
parseStringTest(t, `digraph { subgraph { a -> b } }`)
}
func TestImplicitSubGraph(t *testing.T) {
parseStringTest(t, `digraph { { a -> b } }`)
}
func TestEdges(t *testing.T) {
parseStringTest(t, `digraph { a0 -> a1 -> a2 -> a3 }`)
}
func TestNodes(t *testing.T) {
parseStringTest(t, `digraph { a0 a1 }`)
}
func TestTwoAttributes(t *testing.T) {
g, err := ParseString(`digraph { a0 [shape = circle bla = bla]}`)
check(t, err)
t.Logf("Parsed String = %v", g)
for _, stmt := range g.StmtList {
node := stmt.(*ast.NodeStmt)
if len(node.Attrs[0]) != 2 {
t.Fatalf("Not enough attributes, expected two, but found %v in %v", len(node.Attrs), node)
}
}
}
func TestEasyFsm(t *testing.T) {
parseStringTest(t, `digraph finite_state_machine {
rankdir=LR;
size="8,5";
node [shape = doublecircle]; LR_0 LR_3 LR_4 LR_8;
node [shape = circle];
LR_0 -> LR_2 [ label = "SS(B)" ];
LR_0 -> LR_1 [ label = "SS(S)" ];
LR_1 -> LR_3 [ label = "S($end)" ];
LR_2 -> LR_6 [ label = "SS(b)" ];
LR_2 -> LR_5 [ label = "SS(a)" ];
LR_2 -> LR_4 [ label = "S(A)" ];
LR_5 -> LR_7 [ label = "S(b)" ];
LR_5 -> LR_5 [ label = "S(a)" ];
LR_6 -> LR_6 [ label = "S(b)" ];
LR_6 -> LR_5 [ label = "S(a)" ];
LR_7 -> LR_8 [ label = "S(b)" ];
LR_7 -> LR_5 [ label = "S(a)" ];
LR_8 -> LR_6 [ label = "S(b)" ];
LR_8 -> LR_5 [ label = "S(a)" ];
}`)
}
func TestEmptyAttrList(t *testing.T) {
parseStringTest(t, `digraph g { edge [ ] }`)
}
func TestHelloWorld(t *testing.T) {
parseTest(t, "helloworld.gv.txt")
}
func TestCluster(t *testing.T) {
parseTest(t, "cluster.gv.txt")
}
func TestPsg(t *testing.T) {
parseTest(t, "psg.gv.txt")
}
func TestTransparency(t *testing.T) {
parseTest(t, "transparency.gv.txt")
}
func TestCrazy(t *testing.T) {
parseTest(t, "crazy.gv.txt")
}
func TestKennedyanc(t *testing.T) {
parseTest(t, "kennedyanc.gv.txt")
}
func TestRoot(t *testing.T) {
parseTest(t, "root.gv.txt")
}
func TestTwpoi(t *testing.T) {
parseTest(t, "twopi.gv.txt")
}
func TestDataStruct(t *testing.T) {
parseTest(t, "datastruct.gv.txt")
}
func TestLionShare(t *testing.T) {
parseTest(t, "lion_share.gv.txt")
}
func TestSdh(t *testing.T) {
parseTest(t, "sdh.gv.txt")
}
func TestUnix(t *testing.T) {
parseTest(t, "unix.gv.txt")
}
func TestEr(t *testing.T) {
parseTest(t, "er.gv.txt")
}
func TestNerworkMapTwopi(t *testing.T) {
parseTest(t, "networkmap_twopi.gv.txt")
}
func TestSibling(t *testing.T) {
parseTest(t, "siblings.gv.txt")
}
func TestWorld(t *testing.T) {
parseTest(t, "world.gv.txt")
}
func TestFdpclust(t *testing.T) {
parseTest(t, "fdpclust.gv.txt")
}
func TestPhilo(t *testing.T) {
parseTest(t, "philo.gv.txt")
}
func TestSoftmaint(t *testing.T) {
parseTest(t, "softmaint.gv.txt")
}
func TestFsm(t *testing.T) {
parseTest(t, "fsm.gv.txt")
}
func TestProcess(t *testing.T) {
parseTest(t, "process.gv.txt")
}
func TestSwitchGv(t *testing.T) {
parseTest(t, "switch.gv.txt")
}
func TestGd19942007(t *testing.T) {
parseTest(t, "gd_1994_2007.gv.txt")
}
func TestProfile(t *testing.T) {
parseTest(t, "profile.gv.txt")
}
func TestTrafficLights(t *testing.T) {
parseTest(t, "traffic_lights.gv.txt")
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,52 @@
//Copyright 2013 GoGraphviz Authors
//
//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.
package gographviz
import (
"sort"
)
//Represents the relations between graphs and nodes.
//Each node belongs the main graph or a subgraph.
type Relations struct {
ParentToChildren map[string]map[string]bool
ChildToParents map[string]map[string]bool
}
//Creates an empty set of relations.
func NewRelations() *Relations {
return &Relations{make(map[string]map[string]bool), make(map[string]map[string]bool)}
}
//Adds a node to a parent graph.
func (this *Relations) Add(parent string, child string) {
if _, ok := this.ParentToChildren[parent]; !ok {
this.ParentToChildren[parent] = make(map[string]bool)
}
this.ParentToChildren[parent][child] = true
if _, ok := this.ChildToParents[child]; !ok {
this.ChildToParents[child] = make(map[string]bool)
}
this.ChildToParents[child][parent] = true
}
func (this *Relations) SortedChildren(parent string) []string {
keys := make([]string, 0)
for key := range this.ParentToChildren[parent] {
keys = append(keys, key)
}
sort.Strings(keys)
return keys
}

View File

@@ -0,0 +1,570 @@
// 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.
// A scanner for Go source text. Takes a []byte as source which can
// then be tokenized through repeated calls to the Scan function.
// For a sample use of a scanner, see the implementation of Tokenize.
//
//A scanner for the DOT grammar that has been derived from the standard
//golang scanner with extra added literals.
package scanner
import (
"bytes"
"strconv"
"unicode"
"unicode/utf8"
)
import "github.com/awalterschulze/gographviz/token"
// A Scanner holds the scanner's internal state while processing
// a given text. It can be allocated as part of another data
// structure but must be initialized via Init before use. For
// a sample use, see the implementation of Tokenize.
//
type Scanner struct {
// immutable state
src []byte // source
tokenMap *token.TokenMap
// scanning state
pos token.Position // previous reading position (position before ch)
offset int // current reading offset (position after ch)
ch rune // one char look-ahead
// public state - ok to modify
ErrorCount int // number of errors encountered
}
// Read the next Unicode char into S.ch.
// S.ch < 0 means end-of-file.
//
func (S *Scanner) next() {
if S.offset < len(S.src) {
S.pos.Offset = S.offset
S.pos.Column++
if S.ch == '\n' {
// next character starts a new line
S.pos.Line++
S.pos.Column = 1
}
r, w := rune(S.src[S.offset]), 1
switch {
case r == 0:
S.error(S.pos, "illegal character NUL")
case r >= 0x80:
// not ASCII
r, w = utf8.DecodeRune(S.src[S.offset:])
if r == utf8.RuneError && w == 1 {
S.error(S.pos, "illegal UTF-8 encoding")
}
}
S.offset += w
S.ch = r
} else {
S.pos.Offset = len(S.src)
S.ch = -1 // eof
}
}
// Init prepares the scanner S to tokenize the text src. Calls to Scan
// will use the error handler err if they encounter a syntax error and
// err is not nil. Also, for each error encountered, the Scanner field
// ErrorCount is incremented by one. The filename parameter is used as
// filename in the token.Position returned by Scan for each token. The
// mode parameter determines how comments and illegal characters are
// handled.
//
func (S *Scanner) Init(src []byte, tokenMap *token.TokenMap) {
// Explicitly initialize all fields since a scanner may be reused.
S.src = src
S.tokenMap = tokenMap
S.pos = token.Position{0, 1, 0}
S.offset = 0
S.ErrorCount = 0
S.next()
}
func charString(ch rune) string {
var s string
switch ch {
case -1:
return "EOF"
case '\a':
s = "\\a"
case '\b':
s = "\\b"
case '\f':
s = "\\f"
case '\n':
s = "\\n"
case '\r':
s = "\\r"
case '\t':
s = "\\t"
case '\v':
s = "\\v"
case '\\':
s = "\\\\"
case '\'':
s = "\\'"
default:
s = string(ch)
}
return "'" + s + "' (U+" + strconv.FormatInt(int64(ch), 16) + ")"
}
func (S *Scanner) error(pos token.Position, msg string) {
S.ErrorCount++
}
func (S *Scanner) expect(ch rune) {
if S.ch != ch {
S.error(S.pos, "expected "+charString(ch)+", found "+charString(S.ch))
}
S.next() // always make progress
}
var prefix = []byte("line ")
func (S *Scanner) scanComment(pos token.Position) {
// first '/' or '#' already consumed
if S.ch == '*' {
/*-style comment */
S.expect('*')
for S.ch >= 0 {
ch := S.ch
S.next()
if ch == '*' && S.ch == '/' {
S.next()
return
}
}
} else {
//-style comment or #-style comment
for S.ch >= 0 {
S.next()
if S.ch == '\n' {
// '\n' is not part of the comment for purposes of scanning
// (the comment ends on the same line where it started)
if pos.Column == 1 {
text := S.src[pos.Offset+2 : S.pos.Offset]
if bytes.HasPrefix(text, prefix) {
// comment starts at beginning of line with "//line ";
// get filename and line number, if any
i := bytes.Index(text, []byte{':'})
if i >= 0 {
if line, err := strconv.Atoi(string(text[i+1:])); err == nil && line > 0 {
// valid //line filename:line comment;
// update scanner position
S.pos.Line = line - 1 // -1 since the '\n' has not been consumed yet
}
}
}
}
return
}
}
}
S.error(pos, "comment not terminated")
}
func (S *Scanner) findNewline(pos token.Position) bool {
// first '/' already consumed; assume S.ch == '/' || S.ch == '*'
// read ahead until a newline or non-comment token is found
newline := false
for pos1 := pos; S.ch >= 0; {
if S.ch == '/' {
//-style comment always contains a newline
newline = true
break
}
S.scanComment(pos1)
if pos1.Line < S.pos.Line {
/*-style comment contained a newline */
newline = true
break
}
S.skipWhitespace() // S.insertSemi is set
if S.ch == '\n' {
newline = true
break
}
if S.ch != '/' {
// non-comment token
break
}
pos1 = S.pos
S.next()
if S.ch != '/' && S.ch != '*' {
// non-comment token
break
}
}
// reset position to where it was upon calling findNewline
S.pos = pos
S.offset = pos.Offset + 1
S.next()
return newline
}
func isLetter(ch rune) bool {
return 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' || ch == '_' ||
ch >= 0x80 && unicode.IsLetter(ch) && ch != 'ε'
}
func isDigit(ch rune) bool {
return '0' <= ch && ch <= '9' || ch >= 0x80 && unicode.IsDigit(ch)
}
func digitVal(ch rune) int {
switch {
case '0' <= ch && ch <= '9':
return int(ch) - '0'
case 'a' <= ch && ch <= 'f':
return int(ch) - 'a' + 10
case 'A' <= ch && ch <= 'F':
return int(ch) - 'A' + 10
}
return 16 // larger than any legal digit val
}
func (S *Scanner) scanEscape(quote rune) {
pos := S.pos
var i, base, max uint32
switch S.ch {
case 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\', quote:
S.next()
return
case '0', '1', '2', '3', '4', '5', '6', '7':
i, base, max = 3, 8, 255
case 'x':
S.next()
i, base, max = 2, 16, 255
case 'u':
S.next()
i, base, max = 4, 16, unicode.MaxRune
case 'U':
S.next()
i, base, max = 8, 16, unicode.MaxRune
default:
S.next() // always make progress
S.error(pos, "unknown escape sequence")
return
}
var x uint32
for ; i > 0; i-- {
d := uint32(digitVal(S.ch))
if d > base {
S.error(S.pos, "illegal character in escape sequence")
return
}
x = x*base + d
S.next()
}
if x > max || 0xd800 <= x && x < 0xe000 {
S.error(pos, "escape sequence is invalid Unicode code point")
}
}
func (S *Scanner) scanChar(pos token.Position) {
// '\'' already consumed
n := 0
for S.ch != '\'' {
ch := S.ch
n++
S.next()
if ch == '\n' || ch < 0 {
S.error(pos, "character literal not terminated")
n = 1
break
}
if ch == '\\' {
S.scanEscape('\'')
}
}
S.next()
if n != 1 {
S.error(pos, "illegal character literal")
}
}
func (S *Scanner) isToken(str string) bool {
return S.tokenMap.Type(str) != token.ILLEGAL
}
func (S *Scanner) scanIdentifier() token.Type {
pos := S.pos.Offset
for !S.isToken(string(S.ch)) && !unicode.IsSpace(S.ch) && S.ch != '-' {
S.next()
}
if tok := S.tokenMap.Type(string(S.src[pos:S.pos.Offset])); tok != token.ILLEGAL {
return tok
}
return S.tokenMap.Type("id")
}
func (S *Scanner) scanNumber() token.Type {
for isDigit(S.ch) {
S.next()
}
if S.ch == '.' {
S.next()
for isDigit(S.ch) {
S.next()
}
return S.tokenMap.Type("float_lit")
}
return S.tokenMap.Type("int_lit")
}
func (S *Scanner) scanHTML() token.Type {
count := 1
for count > 0 {
if S.ch == '<' {
count += 1
}
if S.ch == '>' {
count -= 1
}
S.next()
}
return S.tokenMap.Type("html_lit")
}
func (S *Scanner) scanSDTLit(pos token.Position) {
// '<' already consumed
S.next() // consume second <
for cmp := false; !cmp; {
if S.ch < 0 {
S.error(pos, "SDT not terminated")
break
}
if S.ch == '>' {
S.next()
if S.ch == '>' {
break
}
}
S.next()
}
S.next()
}
func (S *Scanner) scanString(pos token.Position) {
// '"' already consumed
for S.ch != '"' {
ch := S.ch
S.next()
if ch == '\n' || ch < 0 {
S.error(pos, "string not terminated")
break
}
if ch == '\\' {
S.scanEscape('"')
}
}
S.next()
}
func (S *Scanner) scanRawString(pos token.Position) {
// '\140' already consumed
for S.ch != '\140' {
ch := S.ch
S.next()
if ch < 0 {
S.error(pos, "string not terminated")
break
}
}
S.next()
}
func (S *Scanner) skipWhitespace() {
for S.ch == ' ' || S.ch == '\t' || S.ch == '\n' || S.ch == '\r' {
S.next()
}
}
// Helper functions for scanning multi-byte tokens such as >> += >>= .
// Different routines recognize different length tok_i based on matches
// of ch_i. If a token ends in '=', the result is tok1 or tok3
// respectively. Otherwise, the result is tok0 if there was no other
// matching character, or tok2 if the matching character was ch2.
func (S *Scanner) switch2(tok0, tok1 token.Type) token.Type {
if S.ch == '=' {
S.next()
return tok1
}
return tok0
}
func (S *Scanner) switch3(tok0, tok1 token.Type, ch2 rune, tok2 token.Type) token.Type {
if S.ch == '=' {
S.next()
return tok1
}
if S.ch == ch2 {
S.next()
return tok2
}
return tok0
}
func (S *Scanner) switch4(tok0, tok1 token.Type, ch2 rune, tok2, tok3 token.Type) token.Type {
if S.ch == '=' {
S.next()
return tok1
}
if S.ch == ch2 {
S.next()
if S.ch == '=' {
S.next()
return tok3
}
return tok2
}
return tok0
}
var semicolon = []byte{';'}
// Scan scans the next token and returns the token position pos,
// the token tok, and the literal text lit corresponding to the
// token. The source end is indicated by token.EOF.
//
// For more tolerant parsing, Scan will return a valid token if
// possible even if a syntax error was encountered. Thus, even
// if the resulting token sequence contains no illegal tokens,
// a client may not assume that no error occurred. Instead it
// must check the scanner's ErrorCount or the number of calls
// of the error handler, if there was one installed.
//
func (S *Scanner) Scan() (*token.Token, token.Position) {
scanAgain:
S.skipWhitespace()
// current token start
pos, tok := S.pos, token.ILLEGAL
// determine token value
switch ch := S.ch; {
case isLetter(ch):
tok = S.scanIdentifier()
case isDigit(ch), ch == '.':
tok = S.scanNumber()
default:
S.next() // always make progress
switch ch {
case -1:
tok = S.tokenMap.Type("$")
case '"':
tok = S.tokenMap.Type("string_lit")
S.scanString(pos)
case '\'':
tok = S.tokenMap.Type("char")
S.scanChar(pos)
case '\140':
tok = S.tokenMap.Type("string_lit")
S.scanRawString(pos)
case ',':
tok = S.tokenMap.Type(",")
case '{':
tok = S.tokenMap.Type("{")
case '}':
tok = S.tokenMap.Type("}")
case ':':
tok = S.tokenMap.Type(":")
case ';':
tok = S.tokenMap.Type(";")
case '+':
tok = S.tokenMap.Type("+")
case '-':
if S.ch == '-' {
tok = S.tokenMap.Type("--")
S.next()
} else if S.ch == '>' {
tok = S.tokenMap.Type("->")
S.next()
} else if isDigit(S.ch) {
tok = S.scanNumber()
} else {
tok = S.tokenMap.Type("-")
}
case '=':
tok = S.tokenMap.Type("=")
case '[':
tok = S.tokenMap.Type("[")
case ']':
tok = S.tokenMap.Type("]")
case '(':
tok = S.tokenMap.Type("(")
case ')':
tok = S.tokenMap.Type(")")
case 'ε':
tok = S.tokenMap.Type("ε")
case '#':
S.scanComment(pos)
goto scanAgain
case '/':
if S.ch == '/' || S.ch == '*' {
// comment
S.scanComment(pos)
goto scanAgain
} else {
tok = S.tokenMap.Type("/")
}
case '|':
tok = S.tokenMap.Type("|")
case '<':
tok = S.scanHTML()
default:
S.error(pos, "illegal character "+charString(ch))
}
}
//fmt.Fprintf(os.Stderr, "return tok %v, %v\n", token.NewToken(tok, S.src[pos.Offset:S.pos.Offset]), pos)
return token.NewToken(tok, S.src[pos.Offset:S.pos.Offset]), pos
}
// An implementation of an ErrorHandler may be provided to the Scanner.
// If a syntax error is encountered and a handler was installed, Error
// is called with a position and an error message. The position points
// to the beginning of the offending token.
//
type ErrorHandler interface {
Error(pos token.Position, msg string)
}
// Within ErrorVector, an error is represented by an Error node. The
// position Pos, if valid, points to the beginning of the offending
// token, and the error condition is described by Msg.
//
type Error struct {
Pos token.Position
Msg string
}
func (e *Error) String() string {
if e.Pos.IsValid() {
// don't print "<unknown position>"
// TODO(gri) reconsider the semantics of Position.IsValid
return e.Pos.String() + ": " + e.Msg
}
return e.Msg
}

View File

@@ -0,0 +1,63 @@
//Copyright 2013 GoGraphviz Authors
//
//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.
package gographviz
import (
"sort"
)
//Represents a Subgraph.
type SubGraph struct {
Attrs Attrs
Name string
}
//Creates a new Subgraph.
func NewSubGraph(name string) *SubGraph {
return &SubGraph{
Attrs: make(Attrs),
Name: name,
}
}
//Represents a set of SubGraphs.
type SubGraphs struct {
SubGraphs map[string]*SubGraph
}
//Creates a new blank set of SubGraphs.
func NewSubGraphs() *SubGraphs {
return &SubGraphs{make(map[string]*SubGraph)}
}
//Adds and creates a new Subgraph to the set of SubGraphs.
func (this *SubGraphs) Add(name string) {
if _, ok := this.SubGraphs[name]; !ok {
this.SubGraphs[name] = NewSubGraph(name)
}
}
func (this *SubGraphs) Sorted() []*SubGraph {
keys := make([]string, 0)
for key := range this.SubGraphs {
keys = append(keys, key)
}
sort.Strings(keys)
s := make([]*SubGraph, len(keys))
for i, key := range keys {
s[i] = this.SubGraphs[key]
}
return s
}

View File

@@ -0,0 +1 @@
These test graphs have been copied from the graphviz gallery found here http://www.graphviz.org/Gallery.php

View File

@@ -0,0 +1,27 @@
digraph G {
subgraph cluster_0 {
style=filled;
color=lightgrey;
node [style=filled,color=white];
a0 -> a1 -> a2 -> a3;
label = "process #1";
}
subgraph cluster_1 {
node [style=filled];
b0 -> b1 -> b2 -> b3;
label = "process #2";
color=blue
}
start -> a0;
start -> b0;
a1 -> b3;
b2 -> a3;
a3 -> a0;
a3 -> end;
b3 -> end;
start [shape=Mdiamond];
end [shape=Msquare];
}

View File

@@ -0,0 +1,104 @@
digraph "unix" {
graph [ fontname = "Helvetica-Oblique",
fontsize = 36,
label = "\n\n\n\nObject Oriented Graphs\nStephen North, 3/19/93",
size = "6,6" ];
node [ shape = polygon,
sides = 4,
distortion = "0.0",
orientation = "0.0",
skew = "0.0",
color = white,
style = filled,
fontname = "Helvetica-Outline" ];
"5th Edition" [sides=9, distortion="0.936354", orientation=28, skew="-0.126818", color=salmon2];
"6th Edition" [sides=5, distortion="0.238792", orientation=11, skew="0.995935", color=deepskyblue];
"PWB 1.0" [sides=8, distortion="0.019636", orientation=79, skew="-0.440424", color=goldenrod2];
LSX [sides=9, distortion="-0.698271", orientation=22, skew="-0.195492", color=burlywood2];
"1 BSD" [sides=7, distortion="0.265084", orientation=26, skew="0.403659", color=gold1];
"Mini Unix" [distortion="0.039386", orientation=2, skew="-0.461120", color=greenyellow];
Wollongong [sides=5, distortion="0.228564", orientation=63, skew="-0.062846", color=darkseagreen];
Interdata [distortion="0.624013", orientation=56, skew="0.101396", color=dodgerblue1];
"Unix/TS 3.0" [sides=8, distortion="0.731383", orientation=43, skew="-0.824612", color=thistle2];
"PWB 2.0" [sides=6, distortion="0.592100", orientation=34, skew="-0.719269", color=darkolivegreen3];
"7th Edition" [sides=10, distortion="0.298417", orientation=65, skew="0.310367", color=chocolate];
"8th Edition" [distortion="-0.997093", orientation=50, skew="-0.061117", color=turquoise3];
"32V" [sides=7, distortion="0.878516", orientation=19, skew="0.592905", color=steelblue3];
V7M [sides=10, distortion="-0.960249", orientation=32, skew="0.460424", color=navy];
"Ultrix-11" [sides=10, distortion="-0.633186", orientation=10, skew="0.333125", color=darkseagreen4];
Xenix [sides=8, distortion="-0.337997", orientation=52, skew="-0.760726", color=coral];
"UniPlus+" [sides=7, distortion="0.788483", orientation=39, skew="-0.526284", color=darkolivegreen3];
"9th Edition" [sides=7, distortion="0.138690", orientation=55, skew="0.554049", color=coral3];
"2 BSD" [sides=7, distortion="-0.010661", orientation=84, skew="0.179249", color=blanchedalmond];
"2.8 BSD" [distortion="-0.239422", orientation=44, skew="0.053841", color=lightskyblue1];
"2.9 BSD" [distortion="-0.843381", orientation=70, skew="-0.601395", color=aquamarine2];
"3 BSD" [sides=10, distortion="0.251820", orientation=18, skew="-0.530618", color=lemonchiffon];
"4 BSD" [sides=5, distortion="-0.772300", orientation=24, skew="-0.028475", color=darkorange1];
"4.1 BSD" [distortion="-0.226170", orientation=38, skew="0.504053", color=lightyellow1];
"4.2 BSD" [sides=10, distortion="-0.807349", orientation=50, skew="-0.908842", color=darkorchid4];
"4.3 BSD" [sides=10, distortion="-0.030619", orientation=76, skew="0.985021", color=lemonchiffon2];
"Ultrix-32" [distortion="-0.644209", orientation=21, skew="0.307836", color=goldenrod3];
"PWB 1.2" [sides=7, distortion="0.640971", orientation=84, skew="-0.768455", color=cyan];
"USG 1.0" [distortion="0.758942", orientation=42, skew="0.039886", color=blue];
"CB Unix 1" [sides=9, distortion="-0.348692", orientation=42, skew="0.767058", color=firebrick];
"USG 2.0" [distortion="0.748625", orientation=74, skew="-0.647656", color=chartreuse4];
"CB Unix 2" [sides=10, distortion="0.851818", orientation=32, skew="-0.020120", color=greenyellow];
"CB Unix 3" [sides=10, distortion="0.992237", orientation=29, skew="0.256102", color=bisque4];
"Unix/TS++" [sides=6, distortion="0.545461", orientation=16, skew="0.313589", color=mistyrose2];
"PDP-11 Sys V" [sides=9, distortion="-0.267769", orientation=40, skew="0.271226", color=cadetblue1];
"USG 3.0" [distortion="-0.848455", orientation=44, skew="0.267152", color=bisque2];
"Unix/TS 1.0" [distortion="0.305594", orientation=75, skew="0.070516", color=orangered];
"TS 4.0" [sides=10, distortion="-0.641701", orientation=50, skew="-0.952502", color=crimson];
"System V.0" [sides=9, distortion="0.021556", orientation=26, skew="-0.729938", color=darkorange1];
"System V.2" [sides=6, distortion="0.985153", orientation=33, skew="-0.399752", color=darkolivegreen4];
"System V.3" [sides=7, distortion="-0.687574", orientation=58, skew="-0.180116", color=lightsteelblue1];
"5th Edition" -> "6th Edition";
"5th Edition" -> "PWB 1.0";
"6th Edition" -> LSX;
"6th Edition" -> "1 BSD";
"6th Edition" -> "Mini Unix";
"6th Edition" -> Wollongong;
"6th Edition" -> Interdata;
Interdata -> "Unix/TS 3.0";
Interdata -> "PWB 2.0";
Interdata -> "7th Edition";
"7th Edition" -> "8th Edition";
"7th Edition" -> "32V";
"7th Edition" -> V7M;
"7th Edition" -> "Ultrix-11";
"7th Edition" -> Xenix;
"7th Edition" -> "UniPlus+";
V7M -> "Ultrix-11";
"8th Edition" -> "9th Edition";
"1 BSD" -> "2 BSD";
"2 BSD" -> "2.8 BSD";
"2.8 BSD" -> "Ultrix-11";
"2.8 BSD" -> "2.9 BSD";
"32V" -> "3 BSD";
"3 BSD" -> "4 BSD";
"4 BSD" -> "4.1 BSD";
"4.1 BSD" -> "4.2 BSD";
"4.1 BSD" -> "2.8 BSD";
"4.1 BSD" -> "8th Edition";
"4.2 BSD" -> "4.3 BSD";
"4.2 BSD" -> "Ultrix-32";
"PWB 1.0" -> "PWB 1.2";
"PWB 1.0" -> "USG 1.0";
"PWB 1.2" -> "PWB 2.0";
"USG 1.0" -> "CB Unix 1";
"USG 1.0" -> "USG 2.0";
"CB Unix 1" -> "CB Unix 2";
"CB Unix 2" -> "CB Unix 3";
"CB Unix 3" -> "Unix/TS++";
"CB Unix 3" -> "PDP-11 Sys V";
"USG 2.0" -> "USG 3.0";
"USG 3.0" -> "Unix/TS 3.0";
"PWB 2.0" -> "Unix/TS 3.0";
"Unix/TS 1.0" -> "Unix/TS 3.0";
"Unix/TS 3.0" -> "TS 4.0";
"Unix/TS++" -> "TS 4.0";
"CB Unix 3" -> "TS 4.0";
"TS 4.0" -> "System V.0";
"System V.0" -> "System V.2";
"System V.2" -> "System V.3";
}

View File

@@ -0,0 +1,114 @@
digraph g {
graph [
rankdir = "LR"
];
node [
fontsize = "16"
shape = "ellipse"
];
edge [
];
"node0" [
label = "<f0> 0x10ba8| <f1>"
shape = "record"
];
"node1" [
label = "<f0> 0xf7fc4380| <f1> | <f2> |-1"
shape = "record"
];
"node2" [
label = "<f0> 0xf7fc44b8| | |2"
shape = "record"
];
"node3" [
label = "<f0> 3.43322790286038071e-06|44.79998779296875|0"
shape = "record"
];
"node4" [
label = "<f0> 0xf7fc4380| <f1> | <f2> |2"
shape = "record"
];
"node5" [
label = "<f0> (nil)| | |-1"
shape = "record"
];
"node6" [
label = "<f0> 0xf7fc4380| <f1> | <f2> |1"
shape = "record"
];
"node7" [
label = "<f0> 0xf7fc4380| <f1> | <f2> |2"
shape = "record"
];
"node8" [
label = "<f0> (nil)| | |-1"
shape = "record"
];
"node9" [
label = "<f0> (nil)| | |-1"
shape = "record"
];
"node10" [
label = "<f0> (nil)| <f1> | <f2> |-1"
shape = "record"
];
"node11" [
label = "<f0> (nil)| <f1> | <f2> |-1"
shape = "record"
];
"node12" [
label = "<f0> 0xf7fc43e0| | |1"
shape = "record"
];
"node0":f0 -> "node1":f0 [
id = 0
];
"node0":f1 -> "node2":f0 [
id = 1
];
"node1":f0 -> "node3":f0 [
id = 2
];
"node1":f1 -> "node4":f0 [
id = 3
];
"node1":f2 -> "node5":f0 [
id = 4
];
"node4":f0 -> "node3":f0 [
id = 5
];
"node4":f1 -> "node6":f0 [
id = 6
];
"node4":f2 -> "node10":f0 [
id = 7
];
"node6":f0 -> "node3":f0 [
id = 8
];
"node6":f1 -> "node7":f0 [
id = 9
];
"node6":f2 -> "node9":f0 [
id = 10
];
"node7":f0 -> "node3":f0 [
id = 11
];
"node7":f1 -> "node1":f0 [
id = 12
];
"node7":f2 -> "node8":f0 [
id = 13
];
"node10":f1 -> "node11":f0 [
id = 14
];
"node10":f2 -> "node12":f0 [
id = 15
];
"node11":f2 -> "node1":f0 [
id = 16
];
}

View File

@@ -0,0 +1,22 @@
graph ER {
node [shape=box]; course; institute; student;
node [shape=ellipse]; {node [label="name"] name0; name1; name2;}
code; grade; number;
node [shape=diamond,style=filled,color=lightgrey]; "C-I"; "S-C"; "S-I";
name0 -- course;
code -- course;
course -- "C-I" [label="n",len=1.00];
"C-I" -- institute [label="1",len=1.00];
institute -- name1;
institute -- "S-I" [label="1",len=1.00];
"S-I" -- student [label="n",len=1.00];
student -- grade;
student -- name2;
student -- number;
student -- "S-C" [label="m",len=1.00];
"S-C" -- course [label="n",len=1.00];
label = "\n\nEntity Relation Diagram\ndrawn by NEATO";
fontsize=20;
}

View File

@@ -0,0 +1,15 @@
graph G {
e
subgraph clusterA {
a -- b;
subgraph clusterC {
C -- D;
}
}
subgraph clusterB {
d -- f
}
d -- D
e -- clusterB
clusterC -- clusterB
}

View File

@@ -0,0 +1,20 @@
digraph finite_state_machine {
rankdir=LR;
size="8,5"
node [shape = doublecircle]; LR_0 LR_3 LR_4 LR_8;
node [shape = circle];
LR_0 -> LR_2 [ label = "SS(B)" ];
LR_0 -> LR_1 [ label = "SS(S)" ];
LR_1 -> LR_3 [ label = "S($end)" ];
LR_2 -> LR_6 [ label = "SS(b)" ];
LR_2 -> LR_5 [ label = "SS(a)" ];
LR_2 -> LR_4 [ label = "S(A)" ];
LR_5 -> LR_7 [ label = "S(b)" ];
LR_5 -> LR_5 [ label = "S(a)" ];
LR_6 -> LR_6 [ label = "S(b)" ];
LR_6 -> LR_5 [ label = "S(a)" ];
LR_7 -> LR_8 [ label = "S(b)" ];
LR_7 -> LR_5 [ label = "S(a)" ];
LR_8 -> LR_6 [ label = "S(b)" ];
LR_8 -> LR_5 [ label = "S(a)" ];
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@
digraph G {Hello->World}

View File

@@ -0,0 +1,90 @@
/*
Note: All images in the file is found at
http://www.graphviz.org/Gallery/directed/images/
-----------
from Kaarle Kaila:
I have implemented Genealogic descendant and ancestor graphs using Graphviz in FinFamily. I have made som description on how to use it with FinFamily at FinFamily wiki-pages at
http://www.finfamily.fi/index.php/Handbook
I attach a descendant graph from Joseph Patrick Kennedy and an ancestor graph from Caroline Bouvier Kennedy as samples from FinFamily. The file georg.jpg is a descendant graph w/o pictures from an imaginary person Georg af Charlow (who has some common attributes with my father) from my testdatabase like the person Charles Charlow has some resemblance to myself.
If you wish to display the attached pictures or wish me to create another ones then feel free to do so. I wish to thank you for Graphviz that let's me create such nice graphs with FinFamily.
regards
Kaarle Kaila
I have this little kennedy database as a sample gedcom file on the download webpage to give international users a few wellknown persons to play with if they wish to try out my software. I originally got it from Michael Kay who is among others Editor at http://www.w3.org/TR/xslt20/. I added the pictures and some data myself.
Attached are both the kennedyanc and kennedydesc files as you requested. I made them as zip-files so that tehy contain both source and destination files. As you email server does not accept zip-files I renamed them to anc.zip ->anc.files and desc.zip to desc.files. Hope these com through your filters.
Graphviz dot program is called from withing FinFamily with a command line such as:
dot -Tjpeg kennedyanc.txt -o kennedyanc.jpg
On page http://www.finfamily.fi/index.php/Graphviz is a description on the different colors together with instructions for finFamily users how to create Graphviz reports.
Kaarle Kaila
Colors and forms symbolize following
* Blue box - man
* Red ellipse - woman
* Blue line - Father/Child relation
* Red line - Mother/Child relation
* Green line - Spouse relation
* Orange line - Ancestors (other) children
* Violet line - Ancestors (other) spouse
*/
/* ancestor graph from Caroline Bouvier Kennedy */
graph G {
I5 [shape=ellipse,color=red,style=bold,label="Caroline Bouvier Kennedy\nb. 27.11.1957 New York",image="images/165px-Caroline_Kennedy.jpg",labelloc=b];
I1 [shape=box,color=blue,style=bold,label="John Fitzgerald Kennedy\nb. 29.5.1917 Brookline\nd. 22.11.1963 Dallas",image="images/kennedyface.jpg",labelloc=b];
I6 [shape=box,color=blue,style=bold,label="John Fitzgerald Kennedy\nb. 25.11.1960 Washington\nd. 16.7.1999 over the Atlantic Ocean, near Aquinnah, MA, USA",image="images/180px-JFKJr2.jpg",labelloc=b];
I7 [shape=box,color=blue,style=bold,label="Patrick Bouvier Kennedy\nb. 7.8.1963\nd. 9.8.1963"];
I2 [shape=ellipse,color=red,style=bold,label="Jaqueline Lee Bouvier\nb. 28.7.1929 Southampton\nd. 19.5.1994 New York City",image="images/jacqueline-kennedy-onassis.jpg",labelloc=b];
I8 [shape=box,color=blue,style=bold,label="Joseph Patrick Kennedy\nb. 6.9.1888 East Boston\nd. 16.11.1969 Hyannis Port",image="images/1025901671.jpg",labelloc=b];
I10 [shape=box,color=blue,style=bold,label="Joseph Patrick Kennedy Jr\nb. 1915\nd. 1944"];
I11 [shape=ellipse,color=red,style=bold,label="Rosemary Kennedy\nb. 13.9.1918\nd. 7.1.2005",image="images/rosemary.jpg",labelloc=b];
I12 [shape=ellipse,color=red,style=bold,label="Kathleen Kennedy\nb. 1920\nd. 1948"];
I13 [shape=ellipse,color=red,style=bold,label="Eunice Mary Kennedy\nb. 10.7.1921 Brookline"];
I9 [shape=ellipse,color=red,style=bold,label="Rose Elizabeth Fitzgerald\nb. 22.7.1890 Boston\nd. 22.1.1995 Hyannis Port",image="images/Rose_kennedy.JPG",labelloc=b];
I15 [shape=box,color=blue,style=bold,label="Aristotle Onassis"];
I3 [shape=box,color=blue,style=bold,label="John Vernou Bouvier III\nb. 1891\nd. 1957",image="images/BE037819.jpg",labelloc=b];
I4 [shape=ellipse,color=red,style=bold,label="Janet Norton Lee\nb. 2.10.1877\nd. 3.1.1968",image="images/n48862003257_1275276_1366.jpg",labelloc=b];
I1 -- I5 [style=bold,color=blue];
I1 -- I6 [style=bold,color=orange];
I2 -- I6 [style=bold,color=orange];
I1 -- I7 [style=bold,color=orange];
I2 -- I7 [style=bold,color=orange];
I1 -- I2 [style=bold,color=violet];
I8 -- I1 [style=bold,color=blue];
I8 -- I10 [style=bold,color=orange];
I9 -- I10 [style=bold,color=orange];
I8 -- I11 [style=bold,color=orange];
I9 -- I11 [style=bold,color=orange];
I8 -- I12 [style=bold,color=orange];
I9 -- I12 [style=bold,color=orange];
I8 -- I13 [style=bold,color=orange];
I9 -- I13 [style=bold,color=orange];
I8 -- I9 [style=bold,color=violet];
I9 -- I1 [style=bold,color=red];
I2 -- I5 [style=bold,color=red];
I2 -- I15 [style=bold,color=violet];
I3 -- I2 [style=bold,color=blue];
I3 -- I4 [style=bold,color=violet];
I4 -- I2 [style=bold,color=red];
}

View File

@@ -0,0 +1,109 @@
##"A few people in the field of genetics are using dot to draw "marriage node diagram" pedigree drawings. Here is one I have done of a test pedigree from the FTREE pedigree drawing package (Lion Share was a racehorse)." Contributed by David Duffy.
##Command to get the layout: "dot -Tpng thisfile > thisfile.png"
digraph Ped_Lion_Share {
# page = "8.2677165,11.692913" ;
ratio = "auto" ;
mincross = 2.0 ;
label = "Pedigree Lion_Share" ;
"001" [shape=box , regular=1,style=filled,fillcolor=white ] ;
"002" [shape=box , regular=1,style=filled,fillcolor=white ] ;
"003" [shape=circle , regular=1,style=filled,fillcolor=white ] ;
"004" [shape=box , regular=1,style=filled,fillcolor=white ] ;
"005" [shape=box , regular=1,style=filled,fillcolor=white ] ;
"006" [shape=circle , regular=1,style=filled,fillcolor=white ] ;
"007" [shape=circle , regular=1,style=filled,fillcolor=white ] ;
"009" [shape=circle , regular=1,style=filled,fillcolor=white ] ;
"014" [shape=circle , regular=1,style=filled,fillcolor=white ] ;
"015" [shape=circle , regular=1,style=filled,fillcolor=white ] ;
"016" [shape=circle , regular=1,style=filled,fillcolor=white ] ;
"ZZ01" [shape=circle , regular=1,style=filled,fillcolor=white ] ;
"ZZ02" [shape=circle , regular=1,style=filled,fillcolor=white ] ;
"017" [shape=circle , regular=1,style=filled,fillcolor=white ] ;
"012" [shape=circle , regular=1,style=filled,fillcolor=white ] ;
"008" [shape=box , regular=1,style=filled,fillcolor=white ] ;
"011" [shape=box , regular=1,style=filled,fillcolor=white ] ;
"013" [shape=box , regular=1,style=filled,fillcolor=white ] ;
"010" [shape=box , regular=1,style=filled,fillcolor=white ] ;
"023" [shape=circle , regular=1,style=filled,fillcolor=white ] ;
"020" [shape=circle , regular=1,style=filled,fillcolor=white ] ;
"021" [shape=circle , regular=1,style=filled,fillcolor=white ] ;
"018" [shape=circle , regular=1,style=filled,fillcolor=white ] ;
"025" [shape=circle , regular=1,style=filled,fillcolor=white ] ;
"019" [shape=box , regular=1,style=filled,fillcolor=white ] ;
"022" [shape=box , regular=1,style=filled,fillcolor=white ] ;
"024" [shape=box , regular=1,style=filled,fillcolor=white ] ;
"027" [shape=circle , regular=1,style=filled,fillcolor=white ] ;
"026" [shape=box , regular=1,style=filled,fillcolor=white ] ;
"028" [shape=box , regular=1,style=filled,fillcolor=grey ] ;
"marr0001" [shape=diamond,style=filled,label="",height=.1,width=.1] ;
"001" -> "marr0001" [dir=none,weight=1] ;
"007" -> "marr0001" [dir=none,weight=1] ;
"marr0001" -> "017" [dir=none, weight=2] ;
"marr0002" [shape=diamond,style=filled,label="",height=.1,width=.1] ;
"001" -> "marr0002" [dir=none,weight=1] ;
"ZZ02" -> "marr0002" [dir=none,weight=1] ;
"marr0002" -> "012" [dir=none, weight=2] ;
"marr0003" [shape=diamond,style=filled,label="",height=.1,width=.1] ;
"002" -> "marr0003" [dir=none,weight=1] ;
"003" -> "marr0003" [dir=none,weight=1] ;
"marr0003" -> "008" [dir=none, weight=2] ;
"marr0004" [shape=diamond,style=filled,label="",height=.1,width=.1] ;
"002" -> "marr0004" [dir=none,weight=1] ;
"006" -> "marr0004" [dir=none,weight=1] ;
"marr0004" -> "011" [dir=none, weight=2] ;
"marr0005" [shape=diamond,style=filled,label="",height=.1,width=.1] ;
"002" -> "marr0005" [dir=none,weight=1] ;
"ZZ01" -> "marr0005" [dir=none,weight=1] ;
"marr0005" -> "013" [dir=none, weight=2] ;
"marr0006" [shape=diamond,style=filled,label="",height=.1,width=.1] ;
"004" -> "marr0006" [dir=none,weight=1] ;
"009" -> "marr0006" [dir=none,weight=1] ;
"marr0006" -> "010" [dir=none, weight=2] ;
"marr0007" [shape=diamond,style=filled,label="",height=.1,width=.1] ;
"005" -> "marr0007" [dir=none,weight=1] ;
"015" -> "marr0007" [dir=none,weight=1] ;
"marr0007" -> "023" [dir=none, weight=2] ;
"marr0008" [shape=diamond,style=filled,label="",height=.1,width=.1] ;
"005" -> "marr0008" [dir=none,weight=1] ;
"016" -> "marr0008" [dir=none,weight=1] ;
"marr0008" -> "020" [dir=none, weight=2] ;
"marr0009" [shape=diamond,style=filled,label="",height=.1,width=.1] ;
"005" -> "marr0009" [dir=none,weight=1] ;
"012" -> "marr0009" [dir=none,weight=1] ;
"marr0009" -> "021" [dir=none, weight=2] ;
"marr0010" [shape=diamond,style=filled,label="",height=.1,width=.1] ;
"008" -> "marr0010" [dir=none,weight=1] ;
"017" -> "marr0010" [dir=none,weight=1] ;
"marr0010" -> "018" [dir=none, weight=2] ;
"marr0011" [shape=diamond,style=filled,label="",height=.1,width=.1] ;
"011" -> "marr0011" [dir=none,weight=1] ;
"023" -> "marr0011" [dir=none,weight=1] ;
"marr0011" -> "025" [dir=none, weight=2] ;
"marr0012" [shape=diamond,style=filled,label="",height=.1,width=.1] ;
"013" -> "marr0012" [dir=none,weight=1] ;
"014" -> "marr0012" [dir=none,weight=1] ;
"marr0012" -> "019" [dir=none, weight=2] ;
"marr0013" [shape=diamond,style=filled,label="",height=.1,width=.1] ;
"010" -> "marr0013" [dir=none,weight=1] ;
"021" -> "marr0013" [dir=none,weight=1] ;
"marr0013" -> "022" [dir=none, weight=2] ;
"marr0014" [shape=diamond,style=filled,label="",height=.1,width=.1] ;
"019" -> "marr0014" [dir=none,weight=1] ;
"020" -> "marr0014" [dir=none,weight=1] ;
"marr0014" -> "024" [dir=none, weight=2] ;
"marr0015" [shape=diamond,style=filled,label="",height=.1,width=.1] ;
"022" -> "marr0015" [dir=none,weight=1] ;
"025" -> "marr0015" [dir=none,weight=1] ;
"marr0015" -> "027" [dir=none, weight=2] ;
"marr0016" [shape=diamond,style=filled,label="",height=.1,width=.1] ;
"024" -> "marr0016" [dir=none,weight=1] ;
"018" -> "marr0016" [dir=none,weight=1] ;
"marr0016" -> "026" [dir=none, weight=2] ;
"marr0017" [shape=diamond,style=filled,label="",height=.1,width=.1] ;
"026" -> "marr0017" [dir=none,weight=1] ;
"027" -> "marr0017" [dir=none,weight=1] ;
"marr0017" -> "028" [dir=none, weight=2] ;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,40 @@
## "It encodes the so-called philosophers dilemma. Neato pretty much approximates the way how humans would layout the graph." Contributed by Manfred Jeusfield.
## Command to generate the layout: "neato -Tpng thisfile > thisfile.png"
digraph PhiloDilemma {
node [shape=box]; bec3; rel3; bec2; rel2; acq2; acq3; bec1; rel1; acq1;
node [shape=circle,fixedsize=true,width=0.9]; hu3; th3; ri3; ea3; hu2; th2; ri2; ea2; hu1; th1; ri1; ea1;
ri3->acq2;
ri3->acq3;
hu3->acq3;
bec3->hu3;
th3->bec3;
rel3->th3;
rel3->ri3;
ea3->rel3;
acq3->ea3;
ri2->acq1;
ri2->acq2;
hu2->acq2;
bec2->hu2;
th2->bec2;
rel2->th2;
rel2->ri2;
ea2->rel2;
acq2->ea2;
ri1->acq3;
ri1->acq1;
hu1->acq1;
bec1->hu1;
th1->bec1;
rel1->th1;
rel1->ri1;
ea1->rel1;
acq1->ea1;
overlap=false
label="PetriNet Model PhiloDilemma\nExtracted from ConceptBase and layed out by Graphviz "
fontsize=12;
}

View File

@@ -0,0 +1,15 @@
graph G {
run -- intr;
intr -- runbl;
runbl -- run;
run -- kernel;
kernel -- zombie;
kernel -- sleep;
kernel -- runmem;
sleep -- swap;
swap -- runswap;
runswap -- new;
runswap -- runmem;
new -- runmem;
sleep -- runmem;
}

View File

@@ -0,0 +1,150 @@
digraph prof {
size="6,4"; ratio = fill;
node [style=filled];
start -> main [color="0.002 0.999 0.999"];
start -> on_exit [color="0.649 0.701 0.701"];
main -> sort [color="0.348 0.839 0.839"];
main -> merge [color="0.515 0.762 0.762"];
main -> term [color="0.647 0.702 0.702"];
main -> signal [color="0.650 0.700 0.700"];
main -> sbrk [color="0.650 0.700 0.700"];
main -> unlink [color="0.650 0.700 0.700"];
main -> newfile [color="0.650 0.700 0.700"];
main -> fclose [color="0.650 0.700 0.700"];
main -> close [color="0.650 0.700 0.700"];
main -> brk [color="0.650 0.700 0.700"];
main -> setbuf [color="0.650 0.700 0.700"];
main -> copyproto [color="0.650 0.700 0.700"];
main -> initree [color="0.650 0.700 0.700"];
main -> safeoutfil [color="0.650 0.700 0.700"];
main -> getpid [color="0.650 0.700 0.700"];
main -> sprintf [color="0.650 0.700 0.700"];
main -> creat [color="0.650 0.700 0.700"];
main -> rem [color="0.650 0.700 0.700"];
main -> oldfile [color="0.650 0.700 0.700"];
sort -> msort [color="0.619 0.714 0.714"];
sort -> filbuf [color="0.650 0.700 0.700"];
sort -> newfile [color="0.650 0.700 0.700"];
sort -> fclose [color="0.650 0.700 0.700"];
sort -> setbuf [color="0.650 0.700 0.700"];
sort -> setfil [color="0.650 0.700 0.700"];
msort -> qsort [color="0.650 0.700 0.700"];
msort -> insert [color="0.650 0.700 0.700"];
msort -> wline [color="0.650 0.700 0.700"];
msort -> div [color="0.650 0.700 0.700"];
msort -> cmpsave [color="0.650 0.700 0.700"];
merge -> insert [color="0.650 0.700 0.700"];
merge -> rline [color="0.650 0.700 0.700"];
merge -> wline [color="0.650 0.700 0.700"];
merge -> unlink [color="0.650 0.700 0.700"];
merge -> fopen [color="0.650 0.700 0.700"];
merge -> fclose [color="0.650 0.700 0.700"];
merge -> setfil [color="0.650 0.700 0.700"];
merge -> mul [color="0.650 0.700 0.700"];
merge -> setbuf [color="0.650 0.700 0.700"];
merge -> cmpsave [color="0.650 0.700 0.700"];
insert -> cmpa [color="0.650 0.700 0.700"];
wline -> flsbuf [color="0.649 0.700 0.700"];
qsort -> cmpa [color="0.650 0.700 0.700"];
rline -> filbuf [color="0.649 0.700 0.700"];
xflsbuf -> write [color="0.650 0.700 0.700"];
flsbuf -> xflsbuf [color="0.649 0.700 0.700"];
filbuf -> read [color="0.650 0.700 0.700"];
term -> unlink [color="0.650 0.700 0.700"];
term -> signal [color="0.650 0.700 0.700"];
term -> setfil [color="0.650 0.700 0.700"];
term -> exit [color="0.650 0.700 0.700"];
endopen -> open [color="0.650 0.700 0.700"];
fopen -> endopen [color="0.639 0.705 0.705"];
fopen -> findiop [color="0.650 0.700 0.700"];
newfile -> fopen [color="0.634 0.707 0.707"];
newfile -> setfil [color="0.650 0.700 0.700"];
fclose -> fflush [color="0.642 0.704 0.704"];
fclose -> close [color="0.650 0.700 0.700"];
fflush -> xflsbuf [color="0.635 0.707 0.707"];
malloc -> morecore [color="0.325 0.850 0.850"];
malloc -> demote [color="0.650 0.700 0.700"];
morecore -> sbrk [color="0.650 0.700 0.700"];
morecore -> getfreehdr [color="0.650 0.700 0.700"];
morecore -> free [color="0.650 0.700 0.700"];
morecore -> getpagesize [color="0.650 0.700 0.700"];
morecore -> putfreehdr [color="0.650 0.700 0.700"];
morecore -> udiv [color="0.650 0.700 0.700"];
morecore -> umul [color="0.650 0.700 0.700"];
on_exit -> malloc [color="0.325 0.850 0.850"];
signal -> sigvec [color="0.650 0.700 0.700"];
moncontrol -> profil [color="0.650 0.700 0.700"];
getfreehdr -> sbrk [color="0.650 0.700 0.700"];
free -> insert [color="0.650 0.700 0.700"];
insert -> getfreehdr [color="0.650 0.700 0.700"];
setfil -> div [color="0.650 0.700 0.700"];
setfil -> rem [color="0.650 0.700 0.700"];
sigvec -> sigblock [color="0.650 0.700 0.700"];
sigvec -> sigsetmask [color="0.650 0.700 0.700"];
doprnt -> urem [color="0.650 0.700 0.700"];
doprnt -> udiv [color="0.650 0.700 0.700"];
doprnt -> strlen [color="0.650 0.700 0.700"];
doprnt -> localeconv [color="0.650 0.700 0.700"];
sprintf -> doprnt [color="0.650 0.700 0.700"];
cmpa [color="0.000 1.000 1.000"];
wline [color="0.201 0.753 1.000"];
insert [color="0.305 0.625 1.000"];
rline [color="0.355 0.563 1.000"];
sort [color="0.408 0.498 1.000"];
qsort [color="0.449 0.447 1.000"];
write [color="0.499 0.386 1.000"];
read [color="0.578 0.289 1.000"];
msort [color="0.590 0.273 1.000"];
merge [color="0.603 0.258 1.000"];
unlink [color="0.628 0.227 1.000"];
filbuf [color="0.641 0.212 1.000"];
open [color="0.641 0.212 1.000"];
sbrk [color="0.647 0.204 1.000"];
signal [color="0.647 0.204 1.000"];
moncontrol [color="0.647 0.204 1.000"];
xflsbuf [color="0.650 0.200 1.000"];
flsbuf [color="0.650 0.200 1.000"];
div [color="0.650 0.200 1.000"];
cmpsave [color="0.650 0.200 1.000"];
rem [color="0.650 0.200 1.000"];
setfil [color="0.650 0.200 1.000"];
close [color="0.650 0.200 1.000"];
fclose [color="0.650 0.200 1.000"];
fflush [color="0.650 0.200 1.000"];
setbuf [color="0.650 0.200 1.000"];
endopen [color="0.650 0.200 1.000"];
findiop [color="0.650 0.200 1.000"];
fopen [color="0.650 0.200 1.000"];
mul [color="0.650 0.200 1.000"];
newfile [color="0.650 0.200 1.000"];
sigblock [color="0.650 0.200 1.000"];
sigsetmask [color="0.650 0.200 1.000"];
sigvec [color="0.650 0.200 1.000"];
udiv [color="0.650 0.200 1.000"];
urem [color="0.650 0.200 1.000"];
brk [color="0.650 0.200 1.000"];
getfreehdr [color="0.650 0.200 1.000"];
strlen [color="0.650 0.200 1.000"];
umul [color="0.650 0.200 1.000"];
doprnt [color="0.650 0.200 1.000"];
copyproto [color="0.650 0.200 1.000"];
creat [color="0.650 0.200 1.000"];
demote [color="0.650 0.200 1.000"];
exit [color="0.650 0.200 1.000"];
free [color="0.650 0.200 1.000"];
getpagesize [color="0.650 0.200 1.000"];
getpid [color="0.650 0.200 1.000"];
initree [color="0.650 0.200 1.000"];
insert [color="0.650 0.200 1.000"];
localeconv [color="0.650 0.200 1.000"];
main [color="0.650 0.200 1.000"];
malloc [color="0.650 0.200 1.000"];
morecore [color="0.650 0.200 1.000"];
oldfile [color="0.650 0.200 1.000"];
on_exit [color="0.650 0.200 1.000"];
profil [color="0.650 0.200 1.000"];
putfreehdr [color="0.650 0.200 1.000"];
safeoutfil [color="0.650 0.200 1.000"];
sprintf [color="0.650 0.200 1.000"];
term [color="0.650 0.200 1.000"];
}

View File

@@ -0,0 +1,32 @@
##"I made a program to generate dot files representing the LR(0) state graph along with computed LALR(1) lookahead for an arbitrary context-free grammar, to make the diagrams I used in this article: http://blog.lab49.com/archives/2471. The program also highlights errant nodes in red if the grammar would produce a shift/reduce or reduce/reduce conflict -- you may be able to go to http://kthielen.dnsalias.com:8082/ to produce a graph more to your liking". Contributed by Kalani Thielen.
##Command to get the layout: "dot -Gsize=10,15 -Tpng thisfile > thisfile.png"
digraph g {
graph [fontsize=30 labelloc="t" label="" splines=true overlap=false rankdir = "LR"];
ratio = auto;
"state0" [ style = "filled, bold" penwidth = 5 fillcolor = "white" fontname = "Courier New" shape = "Mrecord" label =<<table border="0" cellborder="0" cellpadding="3" bgcolor="white"><tr><td bgcolor="black" align="center" colspan="2"><font color="white">State #0</font></td></tr><tr><td align="left" port="r0">&#40;0&#41; s -&gt; &bull;e $ </td></tr><tr><td align="left" port="r1">&#40;1&#41; e -&gt; &bull;l '=' r </td></tr><tr><td align="left" port="r2">&#40;2&#41; e -&gt; &bull;r </td></tr><tr><td align="left" port="r3">&#40;3&#41; l -&gt; &bull;'*' r </td></tr><tr><td align="left" port="r4">&#40;4&#41; l -&gt; &bull;'n' </td></tr><tr><td align="left" port="r5">&#40;5&#41; r -&gt; &bull;l </td></tr></table>> ];
"state1" [ style = "filled" penwidth = 1 fillcolor = "white" fontname = "Courier New" shape = "Mrecord" label =<<table border="0" cellborder="0" cellpadding="3" bgcolor="white"><tr><td bgcolor="black" align="center" colspan="2"><font color="white">State #1</font></td></tr><tr><td align="left" port="r3">&#40;3&#41; l -&gt; &bull;'*' r </td></tr><tr><td align="left" port="r3">&#40;3&#41; l -&gt; '*' &bull;r </td></tr><tr><td align="left" port="r4">&#40;4&#41; l -&gt; &bull;'n' </td></tr><tr><td align="left" port="r5">&#40;5&#41; r -&gt; &bull;l </td></tr></table>> ];
"state2" [ style = "filled" penwidth = 1 fillcolor = "white" fontname = "Courier New" shape = "Mrecord" label =<<table border="0" cellborder="0" cellpadding="3" bgcolor="white"><tr><td bgcolor="black" align="center" colspan="2"><font color="white">State #2</font></td></tr><tr><td align="left" port="r4">&#40;4&#41; l -&gt; 'n' &bull;</td><td bgcolor="grey" align="right">=$</td></tr></table>> ];
"state3" [ style = "filled" penwidth = 1 fillcolor = "white" fontname = "Courier New" shape = "Mrecord" label =<<table border="0" cellborder="0" cellpadding="3" bgcolor="white"><tr><td bgcolor="black" align="center" colspan="2"><font color="white">State #3</font></td></tr><tr><td align="left" port="r5">&#40;5&#41; r -&gt; l &bull;</td><td bgcolor="grey" align="right">=$</td></tr></table>> ];
"state4" [ style = "filled" penwidth = 1 fillcolor = "white" fontname = "Courier New" shape = "Mrecord" label =<<table border="0" cellborder="0" cellpadding="3" bgcolor="white"><tr><td bgcolor="black" align="center" colspan="2"><font color="white">State #4</font></td></tr><tr><td align="left" port="r3">&#40;3&#41; l -&gt; '*' r &bull;</td><td bgcolor="grey" align="right">=$</td></tr></table>> ];
"state5" [ style = "filled" penwidth = 1 fillcolor = "black" fontname = "Courier New" shape = "Mrecord" label =<<table border="0" cellborder="0" cellpadding="3" bgcolor="black"><tr><td bgcolor="black" align="center" colspan="2"><font color="white">State #5</font></td></tr><tr><td align="left" port="r0"><font color="white">&#40;0&#41; s -&gt; e &bull;$ </font></td></tr></table>> ];
"state6" [ style = "filled" penwidth = 1 fillcolor = "white" fontname = "Courier New" shape = "Mrecord" label =<<table border="0" cellborder="0" cellpadding="3" bgcolor="white"><tr><td bgcolor="black" align="center" colspan="2"><font color="white">State #6</font></td></tr><tr><td align="left" port="r1">&#40;1&#41; e -&gt; l &bull;'=' r </td></tr><tr><td align="left" port="r5">&#40;5&#41; r -&gt; l &bull;</td><td bgcolor="grey" align="right">$</td></tr></table>> ];
"state7" [ style = "filled" penwidth = 1 fillcolor = "white" fontname = "Courier New" shape = "Mrecord" label =<<table border="0" cellborder="0" cellpadding="3" bgcolor="white"><tr><td bgcolor="black" align="center" colspan="2"><font color="white">State #7</font></td></tr><tr><td align="left" port="r1">&#40;1&#41; e -&gt; l '=' &bull;r </td></tr><tr><td align="left" port="r3">&#40;3&#41; l -&gt; &bull;'*' r </td></tr><tr><td align="left" port="r4">&#40;4&#41; l -&gt; &bull;'n' </td></tr><tr><td align="left" port="r5">&#40;5&#41; r -&gt; &bull;l </td></tr></table>> ];
"state8" [ style = "filled" penwidth = 1 fillcolor = "white" fontname = "Courier New" shape = "Mrecord" label =<<table border="0" cellborder="0" cellpadding="3" bgcolor="white"><tr><td bgcolor="black" align="center" colspan="2"><font color="white">State #8</font></td></tr><tr><td align="left" port="r1">&#40;1&#41; e -&gt; l '=' r &bull;</td><td bgcolor="grey" align="right">$</td></tr></table>> ];
"state9" [ style = "filled" penwidth = 1 fillcolor = "white" fontname = "Courier New" shape = "Mrecord" label =<<table border="0" cellborder="0" cellpadding="3" bgcolor="white"><tr><td bgcolor="black" align="center" colspan="2"><font color="white">State #9</font></td></tr><tr><td align="left" port="r2">&#40;2&#41; e -&gt; r &bull;</td><td bgcolor="grey" align="right">$</td></tr></table>> ];
state0 -> state5 [ penwidth = 5 fontsize = 28 fontcolor = "black" label = "e" ];
state0 -> state6 [ penwidth = 5 fontsize = 28 fontcolor = "black" label = "l" ];
state0 -> state9 [ penwidth = 5 fontsize = 28 fontcolor = "black" label = "r" ];
state0 -> state1 [ penwidth = 1 fontsize = 14 fontcolor = "grey28" label = "'*'" ];
state0 -> state2 [ penwidth = 1 fontsize = 14 fontcolor = "grey28" label = "'n'" ];
state1 -> state1 [ penwidth = 1 fontsize = 14 fontcolor = "grey28" label = "'*'" ];
state1 -> state4 [ penwidth = 5 fontsize = 28 fontcolor = "black" label = "r" ];
state1 -> state2 [ penwidth = 1 fontsize = 14 fontcolor = "grey28" label = "'n'" ];
state1 -> state3 [ penwidth = 5 fontsize = 28 fontcolor = "black" label = "l" ];
state6 -> state7 [ penwidth = 1 fontsize = 14 fontcolor = "grey28" label = "'='" ];
state7 -> state8 [ penwidth = 5 fontsize = 28 fontcolor = "black" label = "r" ];
state7 -> state1 [ penwidth = 1 fontsize = 14 fontcolor = "grey28" label = "'*'" ];
state7 -> state2 [ penwidth = 1 fontsize = 14 fontcolor = "grey28" label = "'n'" ];
state7 -> state3 [ penwidth = 5 fontsize = 28 fontcolor = "black" label = "l" ];
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,32 @@
##"I made a program to generate dot files representing the LR(0) state graph along with computed LALR(1) lookahead for an arbitrary context-free grammar, to make the diagrams I used in this article: http://blog.lab49.com/archives/2471. The program also highlights errant nodes in red if the grammar would produce a shift/reduce or reduce/reduce conflict -- you may be able to go to http://kthielen.dnsalias.com:8082/ to produce a graph more to your liking". Contributed by Kalani Thielen.
##Command to get the layout: "dot -Gsize=10,15 -Tpng thisfile > thisfile.png"
digraph g {
graph [fontsize=30 labelloc="t" label="" splines=true overlap=false rankdir = "LR"];
ratio = auto;
"state0" [ style = "filled, bold" penwidth = 5 fillcolor = "white" fontname = "Courier New" shape = "Mrecord" label =<<table border="0" cellborder="0" cellpadding="3" bgcolor="white"><tr><td bgcolor="black" align="center" colspan="2"><font color="white">State #0</font></td></tr><tr><td align="left" port="r0">&#40;0&#41; s -&gt; &bull;e $ </td></tr><tr><td align="left" port="r1">&#40;1&#41; e -&gt; &bull;l '=' r </td></tr><tr><td align="left" port="r2">&#40;2&#41; e -&gt; &bull;r </td></tr><tr><td align="left" port="r3">&#40;3&#41; l -&gt; &bull;'*' r </td></tr><tr><td align="left" port="r4">&#40;4&#41; l -&gt; &bull;'n' </td></tr><tr><td align="left" port="r5">&#40;5&#41; r -&gt; &bull;l </td></tr></table>> ];
"state1" [ style = "filled" penwidth = 1 fillcolor = "white" fontname = "Courier New" shape = "Mrecord" label =<<table border="0" cellborder="0" cellpadding="3" bgcolor="white"><tr><td bgcolor="black" align="center" colspan="2"><font color="white">State #1</font></td></tr><tr><td align="left" port="r3">&#40;3&#41; l -&gt; &bull;'*' r </td></tr><tr><td align="left" port="r3">&#40;3&#41; l -&gt; '*' &bull;r </td></tr><tr><td align="left" port="r4">&#40;4&#41; l -&gt; &bull;'n' </td></tr><tr><td align="left" port="r5">&#40;5&#41; r -&gt; &bull;l </td></tr></table>> ];
"state2" [ style = "filled" penwidth = 1 fillcolor = "white" fontname = "Courier New" shape = "Mrecord" label =<<table border="0" cellborder="0" cellpadding="3" bgcolor="white"><tr><td bgcolor="black" align="center" colspan="2"><font color="white">State #2</font></td></tr><tr><td align="left" port="r4">&#40;4&#41; l -&gt; 'n' &bull;</td><td bgcolor="grey" align="right">=$</td></tr></table>> ];
"state3" [ style = "filled" penwidth = 1 fillcolor = "white" fontname = "Courier New" shape = "Mrecord" label =<<table border="0" cellborder="0" cellpadding="3" bgcolor="white"><tr><td bgcolor="black" align="center" colspan="2"><font color="white">State #3</font></td></tr><tr><td align="left" port="r5">&#40;5&#41; r -&gt; l &bull;</td><td bgcolor="grey" align="right">=$</td></tr></table>> ];
"state4" [ style = "filled" penwidth = 1 fillcolor = "white" fontname = "Courier New" shape = "Mrecord" label =<<table border="0" cellborder="0" cellpadding="3" bgcolor="white"><tr><td bgcolor="black" align="center" colspan="2"><font color="white">State #4</font></td></tr><tr><td align="left" port="r3">&#40;3&#41; l -&gt; '*' r &bull;</td><td bgcolor="grey" align="right">=$</td></tr></table>> ];
"state5" [ style = "filled" penwidth = 1 fillcolor = "black" fontname = "Courier New" shape = "Mrecord" label =<<table border="0" cellborder="0" cellpadding="3" bgcolor="black"><tr><td bgcolor="black" align="center" colspan="2"><font color="white">State #5</font></td></tr><tr><td align="left" port="r0"><font color="white">&#40;0&#41; s -&gt; e &bull;$ </font></td></tr></table>> ];
"state6" [ style = "filled" penwidth = 1 fillcolor = "white" fontname = "Courier New" shape = "Mrecord" label =<<table border="0" cellborder="0" cellpadding="3" bgcolor="white"><tr><td bgcolor="black" align="center" colspan="2"><font color="white">State #6</font></td></tr><tr><td align="left" port="r1">&#40;1&#41; e -&gt; l &bull;'=' r </td></tr><tr><td align="left" port="r5">&#40;5&#41; r -&gt; l &bull;</td><td bgcolor="grey" align="right">$</td></tr></table>> ];
"state7" [ style = "filled" penwidth = 1 fillcolor = "white" fontname = "Courier New" shape = "Mrecord" label =<<table border="0" cellborder="0" cellpadding="3" bgcolor="white"><tr><td bgcolor="black" align="center" colspan="2"><font color="white">State #7</font></td></tr><tr><td align="left" port="r1">&#40;1&#41; e -&gt; l '=' &bull;r </td></tr><tr><td align="left" port="r3">&#40;3&#41; l -&gt; &bull;'*' r </td></tr><tr><td align="left" port="r4">&#40;4&#41; l -&gt; &bull;'n' </td></tr><tr><td align="left" port="r5">&#40;5&#41; r -&gt; &bull;l </td></tr></table>> ];
"state8" [ style = "filled" penwidth = 1 fillcolor = "white" fontname = "Courier New" shape = "Mrecord" label =<<table border="0" cellborder="0" cellpadding="3" bgcolor="white"><tr><td bgcolor="black" align="center" colspan="2"><font color="white">State #8</font></td></tr><tr><td align="left" port="r1">&#40;1&#41; e -&gt; l '=' r &bull;</td><td bgcolor="grey" align="right">$</td></tr></table>> ];
"state9" [ style = "filled" penwidth = 1 fillcolor = "white" fontname = "Courier New" shape = "Mrecord" label =<<table border="0" cellborder="0" cellpadding="3" bgcolor="white"><tr><td bgcolor="black" align="center" colspan="2"><font color="white">State #9</font></td></tr><tr><td align="left" port="r2">&#40;2&#41; e -&gt; r &bull;</td><td bgcolor="grey" align="right">$</td></tr></table>> ];
state0 -> state5 [ penwidth = 5 fontsize = 28 fontcolor = "black" label = "e" ];
state0 -> state6 [ penwidth = 5 fontsize = 28 fontcolor = "black" label = "l" ];
state0 -> state9 [ penwidth = 5 fontsize = 28 fontcolor = "black" label = "r" ];
state0 -> state1 [ penwidth = 1 fontsize = 14 fontcolor = "grey28" label = "'*'" ];
state0 -> state2 [ penwidth = 1 fontsize = 14 fontcolor = "grey28" label = "'n'" ];
state1 -> state1 [ penwidth = 1 fontsize = 14 fontcolor = "grey28" label = "'*'" ];
state1 -> state4 [ penwidth = 5 fontsize = 28 fontcolor = "black" label = "r" ];
state1 -> state2 [ penwidth = 1 fontsize = 14 fontcolor = "grey28" label = "'n'" ];
state1 -> state3 [ penwidth = 5 fontsize = 28 fontcolor = "black" label = "l" ];
state6 -> state7 [ penwidth = 1 fontsize = 14 fontcolor = "grey28" label = "'='" ];
state7 -> state8 [ penwidth = 5 fontsize = 28 fontcolor = "black" label = "r" ];
state7 -> state1 [ penwidth = 1 fontsize = 14 fontcolor = "grey28" label = "'*'" ];
state7 -> state2 [ penwidth = 1 fontsize = 14 fontcolor = "grey28" label = "'n'" ];
state7 -> state3 [ penwidth = 5 fontsize = 28 fontcolor = "black" label = "l" ];
}

View File

@@ -0,0 +1,512 @@
/*
This is a graphviz-produced layout of the "family tree" of a fraternity and sorority.
Each member in the graph was assigned a "big brother" from one organization and a "big sister" from the other. Blue icons represent Brothers from the fraternity, Pink represents Sisters from the sorority (Purple members are in both organizations - like honoraries.)
Charter members (who can have no parent nodes) are outlined.
...
dot -Tgif -Goverlap=false -o siblings.gif siblings.dot
We're experimenting with different ways of coloring and graphing, but found this the easiest for now. When we have more people in, we might look at different shades depending on generation number -- earlier people would get lighter colors, more recent members darker. Thumbnail images would be an interesting alteration as well.
from Japheth Cleaver
*/
digraph sdsu {
size="36,36";
node [color=grey, style=filled];
node [fontname="Verdana", size="30,30"];
graph [ fontname = "Arial",
fontsize = 36,
style = "bold",
label = "\nKappa Kappa Psi/Tau Beta Sigma\nSan Diego State University\nEta Mu and Zeta Xi Family Tree\n\nto date: November 30th, 2008\n",
ssize = "30,60" ];
"Lori Brede" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=10"];
"Michael Griffith" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=24"];
"Amie Holston" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=30"];
"Michael Griffith" -> "Lori Brede"
"Amie Holston" -> "Lori Brede"
"Casey Carter" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=11"];
"Laura De'Armond" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=14"];
"Laura De'Armond" -> "Casey Carter"
"Japheth Cleaver" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=12"];
"Chuk Gawlik" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=22"];
"Stacy Snyder" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=309"];
"Chuk Gawlik" -> "Japheth Cleaver"
"Stacy Snyder" -> "Japheth Cleaver"
"Jillian Clifton" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=13"];
"David Guthrie" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=25"];
"David Guthrie" -> "Jillian Clifton"
"Japheth Cleaver" -> "Jillian Clifton"
"Tony Sacco" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=55"];
"Heather Smith" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=59"];
"Tony Sacco" -> "Laura De'Armond"
"Heather Smith" -> "Laura De'Armond"
"Kevin Decker" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=15"];
"Alex Hansen" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=26"];
"Wanda Livelsberger" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=53"];
"Alex Hansen" -> "Kevin Decker"
"Wanda Livelsberger" -> "Kevin Decker"
"Patrick Doerr" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=16"];
"Deanna Jagow" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=23"];
"Alex Hansen" -> "Patrick Doerr"
"Deanna Jagow" -> "Patrick Doerr"
"Lori Asaro" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=178"];
"Mark Pearson" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=169"];
"Lori Ball" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=167"];
"Mark Pearson" -> "Lori Asaro"
"Lori Ball" -> "Lori Asaro"
"Ryan Farris" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=18"];
"Rob Reiner" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=51"];
"Cindy Teel" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=62"];
"Rob Reiner" -> "Ryan Farris"
"Cindy Teel" -> "Ryan Farris"
"Ginger Palmer" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=180"];
"Mark Newton-John" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=46"];
"Mark Newton-John" -> "Ginger Palmer"
"Matthew FitzGerald" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=19"];
"Mervin Maniago" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=41"];
"Mervin Maniago" -> "Matthew FitzGerald"
"Amie Holston" -> "Matthew FitzGerald"
"Tani Miller" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=195"];
"Mark Pearson" -> "Tani Miller"
"Vienna McMurtry" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=196"];
"Robert Walwick" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=153"];
"Robert Walwick" -> "Vienna McMurtry"
"Ginger Palmer" -> "Vienna McMurtry"
"Chuck Foster" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=20"];
"Karen Saye" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=56"];
"Kevin Decker" -> "Chuck Foster"
"Karen Saye" -> "Chuck Foster"
"Gary Frampton" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=201"];
"Ginger Palmer" -> "Gary Frampton"
"Pat Norris" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=207"];
"Sean Tipps" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=204"];
"Teresa Long" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=194"];
"Sean Tipps" -> "Pat Norris"
"Teresa Long" -> "Pat Norris"
"Marc Martin-ez" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=208"];
"Mark Pearson" -> "Marc Martin-ez"
"Tani Miller" -> "Marc Martin-ez"
"Kristen Villone" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=209"];
"Kelly Erickson" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=199"];
"Anna Pedroza" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=197"];
"Kelly Erickson" -> "Kristen Villone"
"Anna Pedroza" -> "Kristen Villone"
"Geoff Frank" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=21"];
"Chris Livelsberger" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=40"];
"Amy Price" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=57"];
"Chris Livelsberger" -> "Geoff Frank"
"Amy Price" -> "Geoff Frank"
"Tracy Murray" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=210"];
"John FitzGibbon" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=92"];
"Judy Dulcich" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=177"];
"John FitzGibbon" -> "Tracy Murray"
"Judy Dulcich" -> "Tracy Murray"
"Ian McIntosh" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=215"];
"Barbara Tollison" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=172"];
"Robert Walwick" -> "Ian McIntosh"
"Barbara Tollison" -> "Ian McIntosh"
"Jayson Smith" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=58"];
"Jayson Smith" -> "Chuk Gawlik"
"Heather Smith" -> "Chuk Gawlik"
"Kelly McKinney" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=222"];
"Mark Nadeau" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=183"];
"Mark Nadeau" -> "Kelly McKinney"
"Judy Dulcich" -> "Kelly McKinney"
"Chris Livelsberger" -> "Deanna Jagow"
"Amy Price" -> "Deanna Jagow"
"Renee Thompson" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=231"];
"J. Angeles" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=3"];
"Kelley Smith" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=223"];
"J. Angeles" -> "Renee Thompson"
"Kelley Smith" -> "Renee Thompson"
"Steven Smith" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=233"];
"John FitzGibbon" -> "Steven Smith"
"Charlene Andrews" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=234"];
"Diane Reoch" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=227"];
"Diane Reoch" -> "Charlene Andrews"
"Tonya Alexander" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=238"];
"Gail Vasquez" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=225"];
"Gail Vasquez" -> "Tonya Alexander"
"Spencer Caldwell" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=239"];
"Becky Bernal" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=218"];
"Becky Bernal" -> "Spencer Caldwell"
"Chuk Gawlik" -> "Michael Griffith"
"Wanda Livelsberger" -> "Michael Griffith"
"Russell Grant" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=242"];
"Steven Smith" -> "Russell Grant"
"Tiffany Worthington" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=66"];
"Chuck Foster" -> "David Guthrie"
"Tiffany Worthington" -> "David Guthrie"
"Jerry Maya" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=250"];
"John FitzGibbon" -> "Jerry Maya"
"Melissa Schwartz" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=252"];
"Russell Grant" -> "Melissa Schwartz"
"Delphy Shaulis" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=255"];
"Renee Thompson" -> "Delphy Shaulis"
"Martin Naiman" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=45"];
"Janean Angeles" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=86"];
"Martin Naiman" -> "Alex Hansen"
"Janean Angeles" -> "Alex Hansen"
"Leslie Harlow" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=265"];
"Dennis McColl" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=251"];
"Denise Luna" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=236"];
"Dennis McColl" -> "Leslie Harlow"
"Denise Luna" -> "Leslie Harlow"
"Jonathan Yudman" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=267"];
"April Ortiz-cloninger" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=258"];
"April Ortiz-cloninger" -> "Jonathan Yudman"
"Michael Elgo" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=268"];
"Carol Kropp" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=254"];
"Spencer Caldwell" -> "Michael Elgo"
"Carol Kropp" -> "Michael Elgo"
"Denmark Vea" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=269"];
"Marc Martin-ez" -> "Denmark Vea"
"Kelley Smith" -> "Denmark Vea"
"Kathleen Hansen" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=27"];
"Martin Naiman" -> "Kathleen Hansen"
"Heather Smith" -> "Kathleen Hansen"
"Laura Stegner" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=274"];
"April Ortiz-cloninger" -> "Laura Stegner"
"Kathy Jones" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=28"];
"J. Angeles" -> "Kathy Jones"
"Eric Gates" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=282"];
"Erick Sugimura" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=280"];
"Erick Sugimura" -> "Eric Gates"
"Laura Stegner" -> "Eric Gates"
"Jennifer Stoewe" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=288"];
"Eric Gates" -> "Jennifer Stoewe"
"Karen Helbling" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=29"];
"Regan Ashker" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=5"];
"Kevin Decker" -> "Karen Helbling"
"Regan Ashker" -> "Karen Helbling"
"Scott Wood" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=295"];
"Eric Gates" -> "Scott Wood"
"Greg Flood" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=200"];
"Greg Flood" -> "J. Angeles"
"Ginger Palmer" -> "J. Angeles"
"Lynn Reeves" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=48"];
"Chuk Gawlik" -> "Amie Holston"
"Lynn Reeves" -> "Amie Holston"
"Susan Colwell" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=302"];
"Michael Elgo" -> "Susan Colwell"
"Christopher Jouan" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=306"];
"Kevin Owens" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=245"];
"Kevin Owens" -> "Christopher Jouan"
"Kristianna Reynante" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=308"];
"Michael Elgo" -> "Kristianna Reynante"
"Janean Angeles" -> "Kristianna Reynante"
"Amy Berner" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=300"];
"Amy Berner" -> "Stacy Snyder"
"Deanna Johnson" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=31"];
"Alex Hansen" -> "Deanna Johnson"
"Laura De'Armond" -> "Deanna Johnson"
"Johnny Richardson" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=310"];
"Russell Grant" -> "Johnny Richardson"
"Nathan Fellhauer" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=313"];
"James Rowland" [color=thistle, URL="http://sdsu.kkytbs.net/members/profile.html?who=52"];
"James Rowland" -> "Nathan Fellhauer"
"Kristianna Reynante" -> "Nathan Fellhauer"
"Brian Raneses" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=314"];
"Sean McHenry" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=42"];
"Sean McHenry" -> "Brian Raneses"
"Penny Lewis" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=315"];
"Martin Naiman" -> "Penny Lewis"
"Becky Graham" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=316"];
"Kristen Elgo" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=7"];
"Kristen Elgo" -> "Becky Graham"
"Steven Gross" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=318"];
"Rob Reiner" -> "Steven Gross"
"Stacy Snyder" -> "Steven Gross"
"Sedona Reynolds" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=32"];
"Mark Newton-John" -> "Sedona Reynolds"
"Cindy Teel" -> "Sedona Reynolds"
"Klair Mayerchak" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=320"];
"Nathan Fellhauer" -> "Klair Mayerchak"
"Becky Graham" -> "Klair Mayerchak"
"Shari VerBerkmoes" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=321"];
"Sean McHenry" -> "Shari VerBerkmoes"
"Janean Angeles" -> "Shari VerBerkmoes"
"Anson Summers" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=326"];
"James Rowland" -> "Anson Summers"
"Dusty Jolliff" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=33"];
"Rob Reiner" -> "Dusty Jolliff"
"Stacy Snyder" -> "Dusty Jolliff"
"Jennifer Garman" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=331"];
"James Rowland" -> "Jennifer Garman"
"Kelly Greenhill" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=333"];
"Rob Reiner" -> "Kelly Greenhill"
"Kristen Elgo" -> "Kelly Greenhill"
"Lucinda Farless" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=334"];
"J. Angeles" -> "Lucinda Farless"
"Susan Colwell" -> "Lucinda Farless"
"Alfredo Cardenas" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=335"];
"Chuk Gawlik" -> "Alfredo Cardenas"
"Kathleen Hansen" -> "Alfredo Cardenas"
"Jennifer Jouan" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=34"];
"Andrea Owens" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=276"];
"Andrea Owens" -> "Jennifer Jouan"
"Tamara Scrivner" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=345"];
"Joseph Butler" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=69"];
"Sarah Maltese" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=83"];
"Joseph Butler" -> "Tamara Scrivner"
"Sarah Maltese" -> "Tamara Scrivner"
"Bradley Stouse" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=346"];
"Ryan Underwood" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=74"];
"Ryan Underwood" -> "Bradley Stouse"
"Cindy Teel" -> "Bradley Stouse"
"Casondra Brimmage" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=347"];
"Kristopher Lininger" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=85"];
"Ilana Melcher" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=73"];
"Kristopher Lininger" -> "Casondra Brimmage"
"Ilana Melcher" -> "Casondra Brimmage"
"Cassiopeia Guthrie" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=348"];
"Jeremy Frazier" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=79"];
"Christine Mount" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=76"];
"Jeremy Frazier" -> "Cassiopeia Guthrie"
"Christine Mount" -> "Cassiopeia Guthrie"
"Kathleen Moran" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=349"];
"Matthew FitzGerald" -> "Kathleen Moran"
"Lori Brede" -> "Kathleen Moran"
"Tiffany Kalland" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=35"];
"Tony Sacco" -> "Tiffany Kalland"
"Karen Helbling" -> "Tiffany Kalland"
"Kristen Anderson" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=350"];
"Jennie Bogart" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=78"];
"David Guthrie" -> "Kristen Anderson"
"Jennie Bogart" -> "Kristen Anderson"
"Laura Simonette" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=351"];
"Jon Weisel" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=89"];
"Jon Weisel" -> "Laura Simonette"
"Japheth Cleaver" -> "Laura Simonette"
"Nathan Williams" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=352"];
"David Guthrie" -> "Nathan Williams"
"Karen Helbling" -> "Nathan Williams"
"Rebecca Hippert" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=353"];
"Ryan Underwood" -> "Rebecca Hippert"
"Tiffany Kalland" -> "Rebecca Hippert"
"Samuel Wallace" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=354"];
"Joseph Butler" -> "Samuel Wallace"
"Deanna Jagow" -> "Samuel Wallace"
"Scott Gardner" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=355"];
"Jeremy Frazier" -> "Scott Gardner"
"Christine Mount" -> "Scott Gardner"
"Alberto Ayon" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=356"];
"Bradley Stouse" -> "Alberto Ayon"
"Jennie Bogart" -> "Alberto Ayon"
"Susannah Clayton" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=357"];
"Nathan Williams" -> "Susannah Clayton"
"Karen Helbling" -> "Susannah Clayton"
"Lisa Gochnauer" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=358"];
"Scott Gardner" -> "Lisa Gochnauer"
"Casondra Brimmage" -> "Lisa Gochnauer"
"Jamie Jackson" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=359"];
"Samuel Wallace" -> "Jamie Jackson"
"Tamara Scrivner" -> "Jamie Jackson"
"Christina Kelly" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=36"];
"Matthew FitzGerald" -> "Christina Kelly"
"Lori Brede" -> "Christina Kelly"
"Gara Thornton" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=360"];
"Mark Newton-John" -> "Gara Thornton"
"Laura Simonette" -> "Gara Thornton"
"Robert Winebarger" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=361"];
"Robin Ellison" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=90"];
"Scott Gardner" -> "Robert Winebarger"
"Robin Ellison" -> "Robert Winebarger"
"Jeremy Kirchner" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=37"];
"Rob Reiner" -> "Jeremy Kirchner"
"Sandy Konar" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=38"];
"Jennifer Brandon" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=9"];
"Jennifer Brandon" -> "Sandy Konar"
"Dan Kuhlman" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=39"];
"Rob Reiner" -> "Dan Kuhlman"
"Dusty Jolliff" -> "Dan Kuhlman"
"Lindsay Arehart" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=4"];
"Martin Naiman" -> "Lindsay Arehart"
"Jennifer Brandon" -> "Lindsay Arehart"
"J. Angeles" -> "Mervin Maniago"
"Kathy Jones" -> "Mervin Maniago"
"Jarrod Monroe" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=43"];
"Jamie Fratacci" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=44"];
"Mark Newton-John" -> "Jarrod Monroe"
"Jamie Fratacci" -> "Jarrod Monroe"
"Chuk Gawlik" -> "Jamie Fratacci"
"Tiffany Worthington" -> "Jamie Fratacci"
"Russell Grant" -> "Martin Naiman"
"Tonya Alexander" -> "Martin Naiman"
"Edward Givens" [color=lightblue, outline=bold, style=bold, URL="http://sdsu.kkytbs.net/members/profile.html?who=106"];
"Edward Givens" -> "Mark Newton-John"
"Veronica Nickel" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=47"];
"Regan Ashker" -> "Veronica Nickel"
"Wanda Livelsberger" -> "Lynn Reeves"
"Bryan Ransom" [color=thistle, URL="http://sdsu.kkytbs.net/members/profile.html?who=49"];
"Jayson Smith" -> "Bryan Ransom"
"Tony Sacco" -> "Regan Ashker"
"Dusty Jolliff" -> "Regan Ashker"
"Jennifer Stout" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=50"];
"Matthew FitzGerald" -> "Jennifer Stout"
"Deanna Jagow" -> "Jennifer Stout"
"Sean McHenry" -> "James Rowland"
"James Rowland" -> "Wanda Livelsberger"
"Janean Angeles" -> "Wanda Livelsberger"
"Melissa Roy" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=54"];
"Mervin Maniago" -> "Melissa Roy"
"Christina Kelly" -> "Melissa Roy"
"Dennis McColl" -> "Tony Sacco"
"April Ortiz-cloninger" -> "Tony Sacco"
"Tony Sacco" -> "Karen Saye"
"Tony Sacco" -> "Amy Price"
"Kathleen Hansen" -> "Amy Price"
"James Rowland" -> "Jayson Smith"
"Brian Raneses" -> "Heather Smith"
"Kristen Elgo" -> "Heather Smith"
"Josh Atwood" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=6"];
"David Guthrie" -> "Josh Atwood"
"Lori Brede" -> "Josh Atwood"
"Katie Browne" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=60"];
"Patrick Doerr" -> "Katie Browne"
"Jamie Fratacci" -> "Katie Browne"
"Kristin Tang" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=61"];
"James Rowland" -> "Kristin Tang"
"Heather Smith" -> "Kristin Tang"
"Mervin Maniago" -> "Cindy Teel"
"Veronica Nickel" -> "Cindy Teel"
"Mike Tulumello" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=63"];
"Matthew FitzGerald" -> "Mike Tulumello"
"Katie Browne" -> "Mike Tulumello"
"Veronica Villanueva" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=64"];
"Ryan Farris" -> "Veronica Villanueva"
"Sedona Reynolds" -> "Veronica Villanueva"
"Mervin Maniago" -> "Tiffany Worthington"
"Jennifer Jouan" -> "Tiffany Worthington"
"Scott Wright" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=67"];
"James Rowland" -> "Scott Wright"
"Kristen Elgo" -> "Scott Wright"
"Jeremy Browne" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=68"];
"Matthew FitzGerald" -> "Jeremy Browne"
"Japheth Cleaver" -> "Jeremy Browne"
"James Fogelman" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=688"];
"Alberto Ayon" -> "James Fogelman"
"Susannah Clayton" -> "James Fogelman"
"Sandra Chase" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=689"];
"David Guthrie" -> "Sandra Chase"
"Japheth Cleaver" -> "Sandra Chase"
"Patrick Doerr" -> "Joseph Butler"
"Deanna Jagow" -> "Joseph Butler"
"Laura Fisher" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=690"];
"Nathan Williams" -> "Laura Fisher"
"Casondra Brimmage" -> "Laura Fisher"
"Katie Kozma" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=691"];
"Scott Wright" -> "Katie Kozma"
"Robin Ellison" -> "Katie Kozma"
"Rachel Perkins" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=692"];
"Joseph Butler" -> "Rachel Perkins"
"Cassiopeia Guthrie" -> "Rachel Perkins"
"Sarah Titilah" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=693"];
"Robert Winebarger" -> "Sarah Titilah"
"Karen Helbling" -> "Sarah Titilah"
"Ashley Rehart" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=694"];
"Laura Fisher" -> "Ashley Rehart"
"Cara Yancey" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=695"];
"Katie Kozma" -> "Cara Yancey"
"Ashley Presley" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=698"];
"Cara Yancey" -> "Ashley Presley"
"Leila Wilhelm" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=699"];
"Robin Ellison" -> "Leila Wilhelm"
"Sean McHenry" -> "Kristen Elgo"
"Stacy Snyder" -> "Kristen Elgo"
"Greg Moody" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=70"];
"Ryan Farris" -> "Greg Moody"
"Jennifer Stout" -> "Greg Moody"
"Lisa Fleck" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=700"];
"Rachel Perkins" -> "Lisa Fleck"
"Christine Coyne" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=701"];
"Rachel Perkins" -> "Christine Coyne"
"Jennifer Cooley" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=702"];
"Laura Fisher" -> "Jennifer Cooley"
"Elizabeth Larios" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=703"];
"Ashley Rehart" -> "Elizabeth Larios"
"Cate Threlkeld" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=707"];
"Katie Kozma" -> "Cate Threlkeld"
"Erika Tapia" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=71"];
"Patrick Doerr" -> "Erika Tapia"
"Melissa Roy" -> "Erika Tapia"
"Robbyn Rozelle" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=72"];
"Jarrod Monroe" -> "Robbyn Rozelle"
"Tiffany Kalland" -> "Robbyn Rozelle"
"Ryan Farris" -> "Ilana Melcher"
"Veronica Villanueva" -> "Ilana Melcher"
"Greg Moody" -> "Ryan Underwood"
"Katie Browne" -> "Ryan Underwood"
"Cameron Brown" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=75"];
"Joseph Butler" -> "Cameron Brown"
"Tiffany Kalland" -> "Cameron Brown"
"Ryan Underwood" -> "Christine Mount"
"Lori Brede" -> "Christine Mount"
"Janay Rabe" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=77"];
"Greg Moody" -> "Janay Rabe"
"Cindy Teel" -> "Janay Rabe"
"Jeremy Browne" -> "Jennie Bogart"
"Tiffany Kalland" -> "Jennie Bogart"
"Ryan Farris" -> "Jeremy Frazier"
"Ilana Melcher" -> "Jeremy Frazier"
"Crystal Bozak" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=8"];
"Patrick Doerr" -> "Crystal Bozak"
"Katie Browne" -> "Crystal Bozak"
"Kameka Smith" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=80"];
"Matthew FitzGerald" -> "Kameka Smith"
"Ilana Melcher" -> "Kameka Smith"
"Kyra Sacco" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=81"];
"Joseph Butler" -> "Kyra Sacco"
"Robbyn Rozelle" -> "Kyra Sacco"
"Samuel Behar" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=82"];
"Ryan Underwood" -> "Samuel Behar"
"Lori Brede" -> "Samuel Behar"
"Patrick Doerr" -> "Sarah Maltese"
"Deanna Jagow" -> "Sarah Maltese"
"David Bronson" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=84"];
"Kristin Alongi-Hutchins" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=87"];
"Tony Sacco" -> "David Bronson"
"Kristin Alongi-Hutchins" -> "David Bronson"
"Cameron Brown" -> "Kristopher Lininger"
"Kameka Smith" -> "Kristopher Lininger"
"Rakan Abu-Rahma" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=852"];
"Christine Coyne" -> "Rakan Abu-Rahma"
"Jennifer Berry" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=270"];
"Jennifer Berry" -> "Janean Angeles"
"Penny Lewis" -> "Kristin Alongi-Hutchins"
"Melissa Bebak" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=88"];
"Greg Moody" -> "Melissa Bebak"
"Sarah Maltese" -> "Melissa Bebak"
"Scott Wright" -> "Jennifer Brandon"
"Japheth Cleaver" -> "Jennifer Brandon"
"Samuel Behar" -> "Robin Ellison"
"Kyra Sacco" -> "Robin Ellison"
"Teresa Simms" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=91"];
"Joseph Butler" -> "Teresa Simms"
"Janay Rabe" -> "Teresa Simms"
"Robert Schmidtke" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=188"];
"Jean Newman" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=166"];
"Robert Schmidtke" -> "John FitzGibbon"
"Jean Newman" -> "John FitzGibbon"
"Brittany DePew" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=928"];
"Elizabeth Larios" -> "Brittany DePew"
"Kathleen Halberg" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=929"];
"Ashley Rehart" -> "Kathleen Halberg"
"Terrance Hirsch" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=96"];
"J. Angeles" -> "Terrance Hirsch"
"Susan Colwell" -> "Terrance Hirsch"
"Monique Arellano" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=972"];
"Ashley Presley" -> "Monique Arellano"
"Anthony Henderson" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=973"];
"Jennifer Cooley" -> "Anthony Henderson"
"Amethyst Tagle" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=974"];
"Cate Threlkeld" -> "Amethyst Tagle"
"Mallory Williams" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=975"];
"Lisa Fleck" -> "Mallory Williams"
}

View File

@@ -0,0 +1,377 @@
digraph G {
size="7,10"
page="8.5,11"
center=""
node[width=.25,height=.375,fontsize=9]
fcfpr1_1_2t_17 -> 341411;
fcfpr1_1t_1 -> 341411;
rdlfpr2_0_rdlt_4 -> 341411;
fpfpr1_0_1t_1 -> 341411;
fpfpr1_1_2t_11 -> 341411;
rtafpr1_1_2t_28 -> 341411;
rtafpr1_1_3t_6 -> 341411;
rdlfpr1_1t_1 -> 358866;
rtafpr1_1_3t_6 -> 358866;
tmfpr1_1_3t_5 -> 358930;
fcfpr1_1_3t_9 -> 358930;
pcfpr1_1_3t_7 -> 358930;
fpfpr1_1_3g_1 -> 358930;
fpfpr1_1_3t_1 -> 358930;
aufpr1_1_3t_1 -> 358930;
rtafpr1_0_3g_1 -> 358930;
rtafpr1_1_3t_6 -> 358930;
msgfpr1_1_1g_12 -> 371943;
rtafpr1_1_1g_8 -> 371943;
rtafpr1_1_1t_35 -> 371943;
rtafpr1_1_1t_45 -> 371943;
rtafpr1_1_3t_6 -> 371943;
tlfpr2_0_rdlg_2 -> 374300;
fcfpr1_1_3t_8 -> 374300;
fcfpr1_1_3t_9 -> 374300;
rtafpr1_1_3t_6 -> 374300;
fcfpr1_0_5g_1 -> 371942;
fcfpr1_1_1t_19 -> 371942;
fcfpr1_1_3t_9 -> 371942;
fcfpr1_1_3t_9 -> 374700;
tymsgfpr1_1_3t_3 -> 374700;
fpfpr1_1_3t_1 -> 374700;
rtafpr1_1_3t_7 -> 374700;
fcfpr1_1_3g_2 -> 374741;
fcfpr1_1_3t_9 -> 374741;
fpfpr1_1_3t_1 -> 374741;
rtafpr1_1_3t_7 -> 374741;
fcfpr1_1_1t_18 -> 374886;
fcfpr1_1_3t_9 -> 374886;
fpfpr1_1_3t_1 -> 374886;
rtafpr1_1_3t_7 -> 374886;
fcfpr1_1_3t_9 -> 375039;
fpfpr1_1_3t_1 -> 375039;
fcfpr1_1_3t_42 -> 375507;
fcfpr1_1_3t_9 -> 375507;
rdlfpr2_0_rdlt_158 -> 375507;
rtafpr1_1_3t_7 -> 375507;
rtafpr1_1_3t_71 -> 375507;
dbfpr1_1_3t_2 -> 375507;
fcfpr1_1_3t_9 -> 375508;
rdlfpr1_1g_13 -> 375508;
rtafpr1_1_3t_7 -> 375508;
rtafpr2_1_rdlg_1 -> 375508;
dbfpr1_1_3t_2 -> 375508;
fcfpr1_1_3t_9 -> 375519;
fpfpr1_1_3g_1 -> 375519;
fpfpr1_1_3t_1 -> 375519;
fcfpr1_1_3t_9 -> 377380;
rdlfpr1_1g_16 -> 377380;
rdlfpr1_1t_100 -> 377380;
fcfpr1_0_2g_1 -> 377719;
fcfpr1_1_3t_10 -> 377719;
fcfpr1_1_3t_7 -> 377719;
fcfpr1_1_3t_9 -> 377719;
rdlfpr2_0_rdlg_12 -> 377719;
rdlfpr2_0_rdlt_108 -> 377719;
rdlfpr2_0_rdlt_27 -> 377719;
rdlfpr2_0_rdlt_30 -> 377719;
fcfpr1_1_3t_9 -> 377763;
fcfpr1_1_3t_9 -> 379848;
fpfpr1_1_3t_1 -> 379848;
fcfpr1_1_3t_9 -> 380571;
fcfpr1_1_3t_9 -> 380604;
fpfpr1_1_3t_1 -> 380604;
fcfpr1_1_3t_9 -> 381211;
fpfpr1_1_3t_1 -> 381211;
fcfpr1_1_3t_9 -> 381835;
fcfpr1_1_3t_9 -> 381897;
fcfpr1_1_3t_9 -> 381901;
fpfpr1_1_3t_1 -> 381901;
fcfpr1_1_3t_9 -> 382103;
rtafpr1_1_3t_7 -> 382103;
fcfpr1_1_3t_9 -> 382161;
fcfpr1_1_3t_9 -> 383174;
fpfpr1_1_3t_1 -> 383174;
rtafpr1_1_3t_7 -> 383174;
fpfpr1_1_3g_1 -> 352010;
fpfpr1_1_3t_1 -> 352010;
fpfpr1_1_3t_1 -> 382409;
fpfpr1_1_3t_1 -> 382827;
fpfpr1_1_3t_1 -> 382928;
rtafpr1_1_3t_7 -> 382928;
tlfpr1_1_1t_5 -> 358224;
tymsgfpr1_1_1t_23 -> 358224;
tymsgfpr1_1_3t_3 -> 358224;
rcfpr0_0_1t_9 -> 358224;
rcfpr1_1_1t_5 -> 358224;
odfpr0_0_1t_8 -> 358224;
odfpr1_1_1t_6 -> 358224;
ecdsgfpr1_1_1t_4 -> 358224;
tymsgfpr1_1_1t_18 -> 358900;
tymsgfpr1_1_3t_3 -> 358900;
rcfpr1_1_1t_100 -> 358900;
rcfpr1_1_1t_22 -> 358900;
rcfpr1_1_1t_37 -> 358900;
odfpr1_1_1t_21 -> 358900;
tymsgfpr1_1_3t_3 -> 372568;
rcfpr1_1_1t_30 -> 372568;
odfpr1_1_1t_31 -> 372568;
tlfpr1_1_1t_20 -> 375557;
tymsgfpr1_1_1t_24 -> 375557;
tymsgfpr1_1_3t_3 -> 375557;
rcfpr1_1_1t_11 -> 375557;
odfpr1_1_1t_9 -> 375557;
ecdsgfpr1_1_1t_19 -> 375557;
rtafpr1_1_1g_14 -> 376956;
rtafpr1_1_1t_64 -> 376956;
rtafpr1_1_2t_18 -> 376956;
rtafpr1_1_3t_30 -> 376956;
rtafpr1_1_3t_7 -> 376956;
rtafpr1_1_3t_7 -> 379339;
rtafpr1_1_1t_14 -> 379422;
rtafpr1_1_1t_20 -> 379422;
rtafpr1_1_3t_7 -> 379422;
rtafpr1_1_3t_7 -> 383039;
fcfpr1_1_1t_18 -> 359471;
fcfpr2_0_1t_1 -> 359471;
fcfpr2_0_1t_2 -> 359471;
ccsfpr2_0_1t_99 -> 359471;
fcfpr1_1_3t_42 -> 384096;
rtafpr1_1_3t_71 -> 384096;
tlfpr1_0_4g_4 -> 354290;
rcfpr0_0_1t_9 -> 354290;
odfpr0_0_1t_8 -> 354290;
pagfpr1_1_1t_23 -> 354290;
rcfpr1_1_1t_5 -> 379864;
rcfpr1_1_1t_100 -> 382574;
rcfpr1_1_1t_22 -> 382574;
rcfpr1_1_1t_37 -> 382574;
rcfpr1_1_1t_30 -> 370706;
rcfpr1_1_1t_30 -> 377908;
rcfpr1_1_1t_30 -> 377924;
rcfpr1_1_1t_30 -> 377971;
rcfpr1_1_1t_30 -> 377980;
odfpr1_1_1t_31 -> 377980;
rcfpr1_1_1t_30 -> 378362;
rcfpr1_1_1t_30 -> 378656;
rcfpr1_1_1t_30 -> 378666;
rcfpr1_1_1t_30 -> 379169;
odfpr1_1_1t_31 -> 379169;
rcfpr1_1_1t_110 -> 379341;
rcfpr1_1_1t_30 -> 379341;
rcfpr1_1_1t_62 -> 379341;
odfpr1_1_1t_31 -> 379341;
rcfpr1_1_1t_30 -> 379972;
rcfpr1_1_1t_30 -> 380298;
rcfpr1_1_1t_30 -> 380448;
rcfpr1_1_1t_30 -> 380475;
odfpr1_1_1t_31 -> 380475;
rcfpr1_1_1t_30 -> 380526;
odfpr1_1_1t_31 -> 357430;
rcfpr1_1_1t_11 -> 379968;
odfpr1_1_1t_9 -> 379968;
ccsfpr2_0_1t_99 -> 359100;
ccsfpr2_0_1t_99 -> 376529;
ccsfpr2_0_1t_99 -> 377801;
ccsfpr2_0_1t_99 -> 379126;
ccsfpr2_0_1t_99 -> 379212;
ccsfpr2_0_1t_99 -> 380285;
ccsfpr2_0_1t_99 -> 380963;
ccsfpr2_0_1t_99 -> 384909;
tlfpr1_0_4g_4 -> 358471;
odfpr0_0_1t_7 -> 358471;
odfpr1_0_1t_36 -> 358471;
odfpr1_0_3t_18 -> 358471;
odfpr1_0_3t_21 -> 358471;
tlfpr1_0_4g_4 -> 375024;
tlfpr1_0_4g_4 -> 375027;
rcfpr1_1_1t_110 -> 381710;
rcfpr1_1_1t_62 -> 381710;
rcfpr1_1_1t_110 -> 381775;
rcfpr1_1_1t_62 -> 381775;
rcfpr1_1_1t_110 -> 382436;
fcfpr1_1_3t_34 -> 382528;
rcfpr1_1_1t_110 -> 382528;
rtafpr1_1_3t_48 -> 382528;
rcfpr1_1_1t_110 -> 382566;
rcfpr1_1_1t_110 -> 382572;
odfpr0_0_1t_7 -> 353506;
rcfpr1_0_1t_35 -> 370509;
odfpr0_0_1t_7 -> 370509;
odfpr0_0_1t_7 -> 370510;
odfpr1_0_1t_38 -> 370510;
tlfpr1_0_4g_5 -> 354546;
rcfpr1_1_1t_61 -> 354546;
odfpr1_0_3t_18 -> 354546;
odfpr1_0_3t_20 -> 354546;
odfpr1_0_3t_18 -> 354757;
odfpr1_0_3t_20 -> 354757;
odfpr1_0_3t_18 -> 354766;
odfpr1_0_3t_20 -> 354766;
odfpr1_0_3t_18 -> 354771;
odfpr1_0_3t_20 -> 354771;
odfpr1_0_3t_18 -> 354785;
odfpr1_0_3t_23 -> 354785;
odfpr1_0_3t_24 -> 354785;
odfpr1_0_3t_18 -> 354878;
odfpr1_0_3t_23 -> 354878;
odfpr1_0_3t_24 -> 354878;
odfpr1_0_3t_18 -> 355080;
odfpr1_0_3t_23 -> 355080;
odfpr1_0_3t_24 -> 355080;
odfpr1_0_3t_18 -> 355288;
odfpr1_0_3t_23 -> 355288;
odfpr1_0_3t_24 -> 355288;
odfpr2_0_03t_13 -> 355288;
odfpr1_0_3t_18 -> 355800;
odfpr1_0_3t_21 -> 355800;
odfpr1_0_3t_18 -> 356116;
odfpr1_0_3t_21 -> 356116;
odfpr1_0_3t_18 -> 356741;
odfpr1_0_3t_21 -> 356741;
odfpr1_0_3t_18 -> 357340;
odfpr1_0_3t_21 -> 357340;
odfpr1_0_3t_18 -> 357538;
odfpr1_0_3t_21 -> 357538;
odfpr1_0_3t_18 -> 357769;
odfpr1_0_3t_21 -> 357769;
odfpr1_0_3t_18 -> 357793;
odfpr1_0_3t_21 -> 357793;
odfpr1_0_3t_18 -> 358155;
odfpr1_0_3t_21 -> 358155;
odfpr1_0_3t_18 -> 358157;
odfpr1_0_3t_21 -> 358157;
odfpr1_0_3t_18 -> 358159;
odfpr1_0_3t_21 -> 358159;
odfpr1_0_3t_18 -> 358584;
odfpr1_0_3t_21 -> 358584;
odfpr1_0_3t_18 -> 360104;
odfpr1_0_3t_21 -> 360104;
odfpr1_0_3t_18 -> 360144;
odfpr1_0_3t_21 -> 360144;
odfpr1_0_3t_18 -> 360672;
odfpr1_0_3t_21 -> 360672;
odfpr1_0_3t_5 -> 360672;
odfpr1_0_3t_18 -> 360839;
odfpr1_0_3t_21 -> 360839;
odfpr1_0_3t_18 -> 371187;
tlfpr1_0_3g_5 -> 373300;
odfpr1_0_3t_12 -> 373300;
odfpr1_0_3t_18 -> 373300;
odfpr1_0_3t_18 -> 375134;
odfpr1_0_5t_18 -> 375134;
rcfpr0_0_1t_10 -> 375319;
odfpr1_0_3t_18 -> 375319;
odfpr1_0_3t_36 -> 375319;
odfpr1_0_5t_17 -> 375319;
odfpr1_0_5t_19 -> 375319;
odfpr1_0_3t_18 -> 375499;
odfpr1_0_3t_18 -> 377220;
odfpr1_0_5t_21 -> 377220;
tlfpr1_0_3g_7 -> 377562;
tlfpr1_1_1t_3 -> 377562;
odfpr1_0_3t_18 -> 377562;
odfpr1_0_3t_36 -> 377562;
odfpr1_0_5t_20 -> 377562;
odfpr1_0_3t_18 -> 378108;
odfpr1_0_3t_6 -> 378108;
odfpr1_0_5t_20 -> 354221;
odfpr0_0_1t_7 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
tlfpr1_0_3g_5 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
odfpr0_0_1t_8 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rcfpr1_1_1t_61 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
fcfpr1_1t_1 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
odfpr1_0_3t_18 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
tlfpr1_0_3g_7 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rcfpr1_1_1t_62 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
ccsfpr2_0_1t_99 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
tymsgfpr1_1_3t_3 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rcfpr0_0_1t_9 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rtafpr1_1_1t_14 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rtafpr1_1_3t_30 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rcfpr1_1_1t_110 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
dbfpr1_1_3t_2 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rtafpr1_1_1g_8 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rcfpr1_1_1t_30 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
tlfpr1_1_1t_20 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rtafpr1_1_1t_64 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
tlfpr2_0_rdlg_2 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rtafpr1_1_2t_28 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
tlfpr1_1_1t_3 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
odfpr1_1_1t_6 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
fpfpr1_1_3t_1 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
aufpr1_1_3t_1 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
fcfpr1_1_3t_34 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rcfpr1_1_1t_5 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
fcfpr1_1_1t_18 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
odfpr1_0_3t_36 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
tlfpr1_1_1t_5 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
fcfpr1_1_1t_19 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
odfpr1_1_1t_9 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
fcfpr1_1_3t_7 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rcfpr1_1_1t_37 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
fcfpr1_1_3t_8 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
odfpr1_1_1t_21 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
fcfpr1_1_3t_9 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rdlfpr2_0_rdlt_27 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
fcfpr1_1_3g_2 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rtafpr1_1_1t_35 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
odfpr1_0_5t_20 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
fpfpr1_1_3g_1 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
odfpr1_0_5t_21 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
fpfpr1_1_2t_11 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
ecdsgfpr1_1_1t_19 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
odfpr1_0_1t_36 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rtafpr1_1_1g_14 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
tymsgfpr1_1_1t_23 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
tymsgfpr1_1_1t_24 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
odfpr1_0_1t_38 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
fcfpr1_0_2g_1 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rdlfpr1_1t_1 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rcfpr0_0_1t_10 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rcfpr1_1_1t_100 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rdlfpr2_0_rdlt_108 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
pcfpr1_1_3t_7 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
odfpr1_0_3t_20 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
ecdsgfpr1_1_1t_4 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
tmfpr1_1_3t_5 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
odfpr1_0_3t_21 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
fpfpr1_0_1t_1 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
odfpr1_0_3t_23 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rcfpr1_1_1t_22 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
pagfpr1_1_1t_23 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rtafpr1_1_3t_71 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rtafpr1_1_2t_18 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rdlfpr2_0_rdlt_158 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rtafpr1_1_3t_6 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
odfpr1_0_3t_24 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rtafpr1_1_3t_7 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rtafpr1_0_3g_1 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rtafpr1_1_1t_20 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rdlfpr1_1g_13 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rcfpr1_0_1t_35 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
fcfpr1_1_2t_17 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rtafpr2_1_rdlg_1 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rdlfpr2_0_rdlt_4 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rdlfpr1_1g_16 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
fcfpr2_0_1t_1 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
fcfpr2_0_1t_2 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rdlfpr1_1t_100 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
msgfpr1_1_1g_12 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rdlfpr2_0_rdlt_30 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
odfpr1_0_3t_5 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
tlfpr1_0_4g_4 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
fcfpr1_1_3t_42 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
odfpr1_0_3t_6 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
tlfpr1_0_4g_5 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rtafpr1_1_3t_48 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
odfpr1_0_5t_17 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
odfpr1_0_5t_18 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
tymsgfpr1_1_1t_18 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
odfpr1_0_5t_19 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
fcfpr1_1_3t_10 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
fcfpr1_0_5g_1 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
odfpr1_0_3t_12 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
odfpr2_0_03t_13 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rcfpr1_1_1t_11 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
odfpr1_1_1t_31 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rdlfpr2_0_rdlg_12 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rtafpr1_1_1t_45 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
}

View File

@@ -0,0 +1,60 @@
digraph G {
graph [center rankdir=LR bgcolor="#808080"]
edge [dir=none]
node [width=0.3 height=0.3 label=""]
{ node [shape=circle style=invis]
1 2 3 4 5 6 7 8 10 20 30 40 50 60 70 80
}
{ node [shape=circle]
a b c d e f g h i j k l m n o p q r s t u v w x
}
{ node [shape=diamond]
A B C D E F G H I J K L M N O P Q R S T U V W X
}
1 -> a -> {A B} [color="#0000ff"]
2 -> b -> {B A} [color="#ff0000"]
3 -> c -> {C D} [color="#ffff00"]
4 -> d -> {D C} [color="#00ff00"]
5 -> e -> {E F} [color="#000000"]
6 -> f -> {F E} [color="#00ffff"]
7 -> g -> {G H} [color="#ffffff"]
8 -> h -> {H G} [color="#ff00ff"]
{ edge [color="#ff0000:#0000ff"]
A -> i -> {I K}
B -> j -> {J L}
}
{ edge [color="#00ff00:#ffff00"]
C -> k -> {K I}
D -> l -> {L J}
}
{ edge [color="#00ffff:#000000"]
E -> m -> {M O}
F -> n -> {N P}
}
{ edge [color="#ff00ff:#ffffff"]
G -> o -> {O M}
H -> p -> {P N}
}
{ edge [color="#00ff00:#ffff00:#ff0000:#0000ff"]
I -> q -> {Q U}
J -> r -> {R V}
K -> s -> {S W}
L -> t -> {T X}
}
{ edge [color="#ff00ff:#ffffff:#00ffff:#000000"]
M -> u -> {U Q}
N -> v -> {V R}
O -> w -> {W S}
P -> x -> {X T}
}
{ edge [color="#ff00ff:#ffffff:#00ffff:#000000:#00ff00:#ffff00:#ff0000:#0000ff"]
Q -> 10
R -> 20
S -> 30
T -> 40
U -> 50
V -> 60
W -> 70
X -> 80
}
}

View File

@@ -0,0 +1,28 @@
##"I played some days with making an interface between our ConceptBase system (essentially a database system to store models) and graphviz. One example graph is attached. It is a so-called petri net for Dutch traffic lights. The example is actually taken from a book by Wil van der Aalst." Contributed by Manfred Jeusfeld.
##Command to produce the output: "neato -Tpng thisfile > thisfile.png"
digraph TrafficLights {
node [shape=box]; gy2; yr2; rg2; gy1; yr1; rg1;
node [shape=circle,fixedsize=true,width=0.9]; green2; yellow2; red2; safe2; safe1; green1; yellow1; red1;
gy2->yellow2;
rg2->green2;
yr2->safe1;
yr2->red2;
safe2->rg2;
green2->gy2;
yellow2->yr2;
red2->rg2;
gy1->yellow1;
rg1->green1;
yr1->safe2;
yr1->red1;
safe1->rg1;
green1->gy1;
yellow1->yr1;
red1->rg1;
overlap=false
label="PetriNet Model TrafficLights\nExtracted from ConceptBase and layed out by Graphviz"
fontsize=12;
}

View File

@@ -0,0 +1,105 @@
graph G {
// graph [splines=true overlap=false]
graph [truecolor bgcolor="#ff00005f"]
node [style=filled fillcolor="#00ff005f"]
1 -- 30 [f=1];
1 -- 40 [f=14];
8 -- 46 [f=1];
8 -- 16 [f=18];
10 -- 25 [f=1];
10 -- 19 [f=5];
10 -- 33 [f=1];
12 -- 8 [f=1];
12 -- 36 [f=5];
12 -- 17 [f=16];
13 -- 38 [f=1];
13 -- 24 [f=19];
24 -- 49 [f=1];
24 -- 13 [f=1];
24 -- 47 [f=12];
24 -- 12 [f=19];
25 -- 27 [f=1];
25 -- 12 [f=1];
27 -- 12 [f=1];
27 -- 14 [f=8];
29 -- 10 [f=1];
29 -- 8 [f=17];
30 -- 24 [f=1];
30 -- 44 [f=15];
38 -- 29 [f=1];
38 -- 35 [f=15];
2 -- 42 [f=2];
2 -- 35 [f=3];
2 -- 11 [f=19];
14 -- 18 [f=2];
14 -- 24 [f=15];
14 -- 38 [f=18];
18 -- 49 [f=2];
18 -- 47 [f=20];
26 -- 41 [f=2];
26 -- 42 [f=15];
31 -- 39 [f=2];
31 -- 47 [f=17];
31 -- 25 [f=14];
37 -- 26 [f=2];
37 -- 16 [f=14];
39 -- 50 [f=2];
39 -- 14 [f=2];
39 -- 18 [f=17];
39 -- 47 [f=10];
41 -- 31 [f=2];
41 -- 8 [f=16];
42 -- 44 [f=2];
42 -- 29 [f=12];
44 -- 37 [f=2];
44 -- 32 [f=15];
3 -- 20 [f=2];
3 -- 28 [f=19];
6 -- 45 [f=2];
6 -- 28 [f=10];
9 -- 6 [f=2];
9 -- 16 [f=1];
15 -- 16 [f=2];
15 -- 48 [f=2];
16 -- 50 [f=2];
16 -- 32 [f=14];
16 -- 39 [f=8];
20 -- 33 [f=2];
33 -- 9 [f=2];
33 -- 46 [f=3];
33 -- 48 [f=17];
45 -- 15 [f=2];
4 -- 17 [f=4];
4 -- 15 [f=6];
4 -- 12 [f=16];
17 -- 21 [f=4];
19 -- 35 [f=4];
19 -- 15 [f=9];
19 -- 43 [f=4];
21 -- 19 [f=4];
21 -- 50 [f=4];
23 -- 36 [f=4];
34 -- 23 [f=4];
34 -- 24 [f=11];
35 -- 34 [f=4];
35 -- 16 [f=6];
35 -- 18 [f=16];
36 -- 46 [f=4];
5 -- 7 [f=1];
5 -- 36 [f=6];
7 -- 32 [f=1];
7 -- 11 [f=2];
7 -- 14 [f=17];
11 -- 40 [f=1];
11 -- 50 [f=1];
22 -- 46 [f=1];
28 -- 43 [f=1];
28 -- 8 [f=18];
32 -- 28 [f=1];
32 -- 39 [f=13];
32 -- 42 [f=15];
40 -- 22 [f=1];
40 -- 47 [f=1];
43 -- 11 [f=1];
43 -- 17 [f=19];
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,54 @@
/* courtesy Ian Darwin and Geoff Collyer, Softquad Inc. */
digraph unix {
size="6,6";
node [color=lightblue2, style=filled];
"5th Edition" -> "6th Edition";
"5th Edition" -> "PWB 1.0";
"6th Edition" -> "LSX";
"6th Edition" -> "1 BSD";
"6th Edition" -> "Mini Unix";
"6th Edition" -> "Wollongong";
"6th Edition" -> "Interdata";
"Interdata" -> "Unix/TS 3.0";
"Interdata" -> "PWB 2.0";
"Interdata" -> "7th Edition";
"7th Edition" -> "8th Edition";
"7th Edition" -> "32V";
"7th Edition" -> "V7M";
"7th Edition" -> "Ultrix-11";
"7th Edition" -> "Xenix";
"7th Edition" -> "UniPlus+";
"V7M" -> "Ultrix-11";
"8th Edition" -> "9th Edition";
"1 BSD" -> "2 BSD";
"2 BSD" -> "2.8 BSD";
"2.8 BSD" -> "Ultrix-11";
"2.8 BSD" -> "2.9 BSD";
"32V" -> "3 BSD";
"3 BSD" -> "4 BSD";
"4 BSD" -> "4.1 BSD";
"4.1 BSD" -> "4.2 BSD";
"4.1 BSD" -> "2.8 BSD";
"4.1 BSD" -> "8th Edition";
"4.2 BSD" -> "4.3 BSD";
"4.2 BSD" -> "Ultrix-32";
"PWB 1.0" -> "PWB 1.2";
"PWB 1.0" -> "USG 1.0";
"PWB 1.2" -> "PWB 2.0";
"USG 1.0" -> "CB Unix 1";
"USG 1.0" -> "USG 2.0";
"CB Unix 1" -> "CB Unix 2";
"CB Unix 2" -> "CB Unix 3";
"CB Unix 3" -> "Unix/TS++";
"CB Unix 3" -> "PDP-11 Sys V";
"USG 2.0" -> "USG 3.0";
"USG 3.0" -> "Unix/TS 3.0";
"PWB 2.0" -> "Unix/TS 3.0";
"Unix/TS 1.0" -> "Unix/TS 3.0";
"Unix/TS 3.0" -> "TS 4.0";
"Unix/TS++" -> "TS 4.0";
"CB Unix 3" -> "TS 4.0";
"TS 4.0" -> "System V.0";
"System V.0" -> "System V.2";
"System V.2" -> "System V.3";
}

View File

@@ -0,0 +1,67 @@
digraph world {
size="7,7";
{rank=same; S8 S24 S1 S35 S30;}
{rank=same; T8 T24 T1 T35 T30;}
{rank=same; 43 37 36 10 2;}
{rank=same; 25 9 38 40 13 17 12 18;}
{rank=same; 26 42 11 3 33 19 39 14 16;}
{rank=same; 4 31 34 21 41 28 20;}
{rank=same; 27 5 22 32 29 15;}
{rank=same; 6 23;}
{rank=same; 7;}
S8 -> 9;
S24 -> 25;
S24 -> 27;
S1 -> 2;
S1 -> 10;
S35 -> 43;
S35 -> 36;
S30 -> 31;
S30 -> 33;
9 -> 42;
9 -> T1;
25 -> T1;
25 -> 26;
27 -> T24;
2 -> {3 ; 16 ; 17 ; T1 ; 18}
10 -> { 11 ; 14 ; T1 ; 13; 12;}
31 -> T1;
31 -> 32;
33 -> T30;
33 -> 34;
42 -> 4;
26 -> 4;
3 -> 4;
16 -> 15;
17 -> 19;
18 -> 29;
11 -> 4;
14 -> 15;
37 -> {39 ; 41 ; 38 ; 40;}
13 -> 19;
12 -> 29;
43 -> 38;
43 -> 40;
36 -> 19;
32 -> 23;
34 -> 29;
39 -> 15;
41 -> 29;
38 -> 4;
40 -> 19;
4 -> 5;
19 -> {21 ; 20 ; 28;}
5 -> {6 ; T35 ; 23;}
21 -> 22;
20 -> 15;
28 -> 29;
6 -> 7;
15 -> T1;
22 -> T35;
22 -> 23;
29 -> T30;
7 -> T8;
23 -> T24;
23 -> T1;
}

View File

@@ -0,0 +1,54 @@
//Copyright 2013 GoGraphviz Authors
//
//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.
package token
var DOTTokens = NewMapFromStrings([]string{
"ε",
"id",
"{",
"}",
";",
"=",
"[",
"]",
",",
":",
"->",
"--",
"graph",
"Graph",
"GRAPH",
"strict",
"Strict",
"STRICT",
"digraph",
"Digraph",
"DiGraph",
"DIGRAPH",
"node",
"Node",
"NODE",
"edge",
"Edge",
"EDGE",
"subgraph",
"Subgraph",
"SubGraph",
"SUBGRAPH",
"string_lit",
"int_lit",
"float_lit",
"html_lit",
})

View File

@@ -0,0 +1,242 @@
//Copyright 2013 GoGraphviz Authors
//
//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.
package token
import (
"bytes"
"fmt"
"io/ioutil"
"regexp"
"strconv"
"strings"
)
type Token struct {
Type Type
Lit []byte
}
func NewToken(typ Type, lit []byte) *Token {
return &Token{typ, lit}
}
func (this *Token) Equals(that *Token) bool {
if this == nil || that == nil {
return this == that
}
if this.Type != that.Type {
return false
}
return bytes.Equal(this.Lit, that.Lit)
}
func (this *Token) String() string {
str := ""
if this.Type == EOF {
str += "\"$\""
} else {
str += "\"" + string(this.Lit) + "\""
}
str += "(" + strconv.Itoa(int(this.Type)) + ")"
return str
}
type Type int
const (
ILLEGAL Type = iota - 1
EOF
)
func (T Type) String() string {
return strconv.Itoa(int(T))
}
// Position describes an arbitrary source position
// including the file, line, and column location.
// A Position is valid if the line number is > 0.
//
type Position struct {
Offset int // offset, starting at 0
Line int // line number, starting at 1
Column int // column number, starting at 1 (character count)
}
// IsValid returns true if the position is valid.
func (pos *Position) IsValid() bool { return pos.Line > 0 }
// String returns a string in one of several forms:
//
// file:line:column valid position with file name
// line:column valid position without file name
// file invalid position with file name
// - invalid position without file name
//
func (pos Position) String() string {
s := ""
if pos.IsValid() {
s += fmt.Sprintf("%d:%d", pos.Line, pos.Column)
}
if s == "" {
s = "-"
}
return s
}
func (T *Token) IntValue() (int64, error) {
return strconv.ParseInt(string(T.Lit), 10, 64)
}
func (T *Token) UintValue() (uint64, error) {
return strconv.ParseUint(string(T.Lit), 10, 64)
}
func (T *Token) SDTVal() string {
sdt := string(T.Lit)
rex, err := regexp.Compile("\\$[0-9]+")
if err != nil {
panic(err)
}
idx := rex.FindAllStringIndex(sdt, -1)
res := ""
if len(idx) <= 0 {
res = sdt
} else {
for i, loc := range idx {
if loc[0] > 0 {
if i > 0 {
res += sdt[idx[i-1][1]:loc[0]]
} else {
res += sdt[0:loc[0]]
}
}
res += "X["
res += sdt[loc[0]+1 : loc[1]]
res += "]"
}
if idx[len(idx)-1][1] < len(sdt) {
res += sdt[idx[len(idx)-1][1]:]
}
}
return strings.TrimSpace(res[2 : len(res)-2])
}
//*********** Tokenmap
type TokenMap struct {
tokenMap []string
stringMap map[string]Type
}
func NewMap() *TokenMap {
tm := &TokenMap{make([]string, 0, 10), make(map[string]Type)}
tm.AddToken("$")
tm.AddToken("ε")
return tm
}
func (this *TokenMap) AddToken(str string) {
if _, exists := this.stringMap[str]; exists {
return
}
this.stringMap[str] = Type(len(this.tokenMap))
this.tokenMap = append(this.tokenMap, str)
}
func NewMapFromFile(file string) (*TokenMap, error) {
src, err := ioutil.ReadFile(file)
if err != nil {
return nil, err
}
return NewMapFromString(string(src)), nil
}
func NewMapFromStrings(input []string) *TokenMap {
tm := NewMap()
for _, s := range input {
tm.AddToken(s)
}
return tm
}
func NewMapFromString(input string) *TokenMap {
tokens := strings.Fields(input)
return NewMapFromStrings(tokens)
}
func (this *TokenMap) Type(key string) Type {
tok, ok := this.stringMap[key]
if !ok {
return ILLEGAL
}
return tok
}
func (this *TokenMap) TokenString(typ Type) string {
tok := int(typ)
if tok < 0 || tok >= len(this.tokenMap) {
return "illegal " + strconv.Itoa(tok)
}
return this.tokenMap[tok]
}
func (this *TokenMap) String() string {
res := ""
for str, tok := range this.stringMap {
res += str + " : " + strconv.Itoa(int(tok)) + "\n"
}
return res
}
func (this *TokenMap) Strings() []string {
return this.tokenMap[1:]
}
func (this *TokenMap) Equals(that *TokenMap) bool {
if this == nil || that == nil {
return false
}
if len(this.stringMap) != len(that.stringMap) ||
len(this.tokenMap) != len(that.tokenMap) {
return false
}
for str, tok := range this.stringMap {
if tok1, ok := that.stringMap[str]; !ok || tok1 != tok {
return false
}
}
return true
}
func (this *TokenMap) Tokens() []*Token {
res := make([]*Token, 0, len(this.stringMap))
for typ, str := range this.tokenMap {
res = append(res, &Token{Type(typ), []byte(str)})
}
return res
}
func (this *TokenMap) WriteFile(file string) error {
out := ""
for i := 1; i < len(this.tokenMap); i++ {
out += this.TokenString(Type(i)) + "\n"
}
return ioutil.WriteFile(file, []byte(out), 0644)
}

136
vendor/github.com/awalterschulze/gographviz/write.go generated vendored Normal file
View File

@@ -0,0 +1,136 @@
//Copyright 2013 GoGraphviz Authors
//
//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.
package gographviz
import (
"fmt"
"github.com/awalterschulze/gographviz/ast"
)
type writer struct {
*Graph
writtenLocations map[string]bool
}
func newWriter(g *Graph) *writer {
return &writer{g, make(map[string]bool)}
}
func appendAttrs(list ast.StmtList, attrs Attrs) ast.StmtList {
for _, name := range attrs.SortedNames() {
stmt := &ast.Attr{
Field: ast.Id(name),
Value: ast.Id(attrs[name]),
}
list = append(list, stmt)
}
return list
}
func (this *writer) newSubGraph(name string) *ast.SubGraph {
sub := this.SubGraphs.SubGraphs[name]
this.writtenLocations[sub.Name] = true
s := &ast.SubGraph{}
s.Id = ast.Id(sub.Name)
s.StmtList = appendAttrs(s.StmtList, sub.Attrs)
children := this.Relations.SortedChildren(name)
for _, child := range children {
s.StmtList = append(s.StmtList, this.newNodeStmt(child))
}
return s
}
func (this *writer) newNodeId(name string, port string) *ast.NodeId {
node := this.Nodes.Lookup[name]
return ast.MakeNodeId(node.Name, port)
}
func (this *writer) newNodeStmt(name string) *ast.NodeStmt {
node := this.Nodes.Lookup[name]
id := ast.MakeNodeId(node.Name, "")
this.writtenLocations[node.Name] = true
return &ast.NodeStmt{
id,
ast.PutMap(node.Attrs),
}
}
func (this *writer) newLocation(name string, port string) ast.Location {
if this.IsNode(name) {
return this.newNodeId(name, port)
} else if this.IsSubGraph(name) {
if len(port) != 0 {
panic(fmt.Sprintf("subgraph cannot have a port: %v", port))
}
return this.newSubGraph(name)
}
panic(fmt.Sprintf("%v is not a node or a subgraph", name))
}
func (this *writer) newEdgeStmt(edge *Edge) *ast.EdgeStmt {
src := this.newLocation(edge.Src, edge.SrcPort)
dst := this.newLocation(edge.Dst, edge.DstPort)
stmt := &ast.EdgeStmt{
Source: src,
EdgeRHS: ast.EdgeRHS{
&ast.EdgeRH{
ast.EdgeOp(edge.Dir),
dst,
},
},
Attrs: ast.PutMap(edge.Attrs),
}
return stmt
}
func (this *writer) Write() *ast.Graph {
t := &ast.Graph{}
t.Strict = this.Strict
t.Type = ast.GraphType(this.Directed)
t.Id = ast.Id(this.Name)
t.StmtList = appendAttrs(t.StmtList, this.Attrs)
for _, edge := range this.Edges.Edges {
t.StmtList = append(t.StmtList, this.newEdgeStmt(edge))
}
subGraphs := this.SubGraphs.Sorted()
for _, s := range subGraphs {
if _, ok := this.writtenLocations[s.Name]; !ok {
t.StmtList = append(t.StmtList, this.newSubGraph(s.Name))
}
}
nodes := this.Nodes.Sorted()
for _, n := range nodes {
if _, ok := this.writtenLocations[n.Name]; !ok {
t.StmtList = append(t.StmtList, this.newNodeStmt(n.Name))
}
}
return t
}
//Creates an Abstract Syntrax Tree from the Graph.
func (g *Graph) WriteAst() *ast.Graph {
w := newWriter(g)
return w.Write()
}
//Returns a DOT string representing the Graph.
func (g *Graph) String() string {
return g.WriteAst().String()
}

11
vendor/github.com/aws/aws-sdk-go/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,11 @@
dist
/doc
/doc-staging
.yardoc
Gemfile.lock
awstesting/integration/smoke/**/importmarker__.go
awstesting/integration/smoke/_test/
/vendor/bin/
/vendor/pkg/
/vendor/src/
/private/model/cli/gen-api/gen-api

14
vendor/github.com/aws/aws-sdk-go/.godoc_config generated vendored Normal file
View File

@@ -0,0 +1,14 @@
{
"PkgHandler": {
"Pattern": "/sdk-for-go/api/",
"StripPrefix": "/sdk-for-go/api",
"Include": ["/src/github.com/aws/aws-sdk-go/aws", "/src/github.com/aws/aws-sdk-go/service"],
"Exclude": ["/src/cmd", "/src/github.com/aws/aws-sdk-go/awstesting", "/src/github.com/aws/aws-sdk-go/awsmigrate"],
"IgnoredSuffixes": ["iface"]
},
"Github": {
"Tag": "master",
"Repo": "/aws/aws-sdk-go",
"UseGithub": true
}
}

24
vendor/github.com/aws/aws-sdk-go/.travis.yml generated vendored Normal file
View File

@@ -0,0 +1,24 @@
language: go
sudo: false
go:
- 1.5
- 1.6
- 1.7
- 1.8
- tip
# Use Go 1.5's vendoring experiment for 1.5 tests.
env:
- GO15VENDOREXPERIMENT=1
install:
- make get-deps
script:
- make unit-with-race-cover
matrix:
allow_failures:
- go: tip

804
vendor/github.com/aws/aws-sdk-go/CHANGELOG.md generated vendored Normal file
View File

@@ -0,0 +1,804 @@
Release v1.8.0 (2017-03-22)
===
Service Client Updates
---
* `service/codebuild`: Updates service documentation
* `service/directconnect`: Updates service API
* Deprecated DescribeConnectionLoa, DescribeInterconnectLoa, AllocateConnectionOnInterconnect and DescribeConnectionsOnInterconnect operations in favor of DescribeLoa, DescribeLoa, AllocateHostedConnection and DescribeHostedConnections respectively.
* `service/marketplacecommerceanalytics`: Updates service API, documentation, and paginators
* This update adds a new data set, us_sales_and_use_tax_records, which enables AWS Marketplace sellers to programmatically access to their U.S. Sales and Use Tax report data.
* `service/pinpoint`: Updates service API and documentation
* Amazon Pinpoint User Segmentation
* Added ability to segment endpoints by user attributes in addition to endpoint attributes. Amazon Pinpoint Event Stream Preview
* Added functionality to publish raw app analytics and campaign events data as events streams to Kinesis and Kinesis Firehose
* The feature provides developers with increased flexibility of exporting raw events to S3, Redshift, Elasticsearch using a Kinesis Firehose stream or enable real time event processing use cases using a Kinesis stream
* `service/rekognition`: Updates service documentation.
SDK Features
---
* `aws/request`: Add support for context.Context to SDK API operation requests (#1132)
* Adds support for context.Context to the SDK by adding `WithContext` methods for each API operation, Paginators and Waiters. e.g `PutObjectWithContext`. This change also adds the ability to provide request functional options to the method calls instead of requiring you to use the `Request` API operation method (e.g `PutObjectRequest`).
* Adds a `Complete` Request handler list that will be called ever time a request is completed. This includes both success and failure. Complete will only be called once per API operation request.
* `private/waiter` package moved from the private group to `aws/request/waiter` and made publicly available.
* Adds Context support to all API operations, Waiters(WaitUntil) and Paginators(Pages) methods.
* Adds Context support for s3manager and s3crypto clients.
SDK Enhancements
---
* `aws/signer/v4`: Adds support for unsigned payload signer config (#1130)
* Adds configuration option to the v4.Signer to specify the request's body should not be signed. This will only correclty function on services that support unsigned payload. e.g. S3, Glacier.
SDK Bug Fixes
---
* `service/s3`: Fix S3 HostID to be available in S3 request error message (#1131)
* Adds a new type s3.RequestFailure which exposes the S3 HostID value from a S3 API operation response. This is helpful when you have an error with S3, and need to contact support. Both RequestID and HostID are needed.
* `private/model/api`: Do not return a link if uid is empty (#1133)
* Fixes SDK's doc generation to not generate API reference doc links if the SDK us unable to create a valid link.
* `aws/request`: Optimization to handler list copy to prevent multiple alloc calls. (#1134)
Release v1.7.9 (2017-03-13)
===
Service Client Updates
---
* `service/devicefarm`: Updates service API, documentation, paginators, and examples
* Network shaping allows users to simulate network connections and conditions while testing their Android, iOS, and web apps with AWS Device Farm.
* `service/cloudwatchevents`: Updates service API, documentation, and examples
SDK Enhancement
===
* `aws/session`: Add support for side loaded CA bundles (#1117)
* Adds supports for side loading Certificate Authority bundle files to the SDK using AWS_CA_BUNDLE environment variable or CustomCABundle session option.
* `service/s3/s3crypto`: Add support for AES/CBC/PKCS5Padding (#1124)
SDK Bug
===
* `service/rds`: Fixing issue when not providing `SourceRegion` on cross
region operations (#1127)
* `service/rds`: Enables cross region for `CopyDBClusterSnapshot` and
`CreateDBCluster` (#1128)
Release v1.7.8 (2017-03-10)
===
Service Client Updates
---
* `service/codedeploy`: Updates service paginators
* Add paginators for Codedeploy
* `service/emr`: Updates service API, documentation, and paginators
* This release includes support for instance fleets in Amazon EMR.
Release v1.7.7 (2017-03-09)
===
Service Client Updates
---
* `service/apigateway`: Updates service API, documentation, and paginators
* API Gateway has added support for ACM certificates on custom domain names. Both Amazon-issued certificates and uploaded third-part certificates are supported.
* `service/clouddirectory`: Updates service API, documentation, and paginators
* Introduces a new Cloud Directory API that enables you to retrieve all available parent paths for any type of object (a node, leaf node, policy node, and index node) in a hierarchy.
Release v1.7.6 (2017-03-09)
===
Service Client Updates
---
* `service/organizations`: Updates service documentation and examples
* Doc-only Update for Organizations: Add SDK Code Snippets
* `service/workdocs`: Adds new service
* The Administrative SDKs for Amazon WorkDocs provides full administrator level access to WorkDocs site resources, allowing developers to integrate their applications to manage WorkDocs users, content and permissions programmatically
Release v1.7.5 (2017-03-08)
===
Service Client Updates
---
* `aws/endpoints`: Updated Regions and Endpoints metadata.
* `service/rds`: Updates service API and documentation
* Add support to using encrypted clusters as cross-region replication masters. Update CopyDBClusterSnapshot API to support encrypted cross region copy of Aurora cluster snapshots.
Release v1.7.4 (2017-03-06)
===
Service Client Updates
---
* `service/budgets`: Updates service API and paginators
* When creating or editing a budget via the AWS Budgets API you can define notifications that are sent to subscribers when the actual or forecasted value for cost or usage exceeds the notificationThreshold associated with the budget notification object. Starting today, the maximum allowed value for the notificationThreshold was raised from 100 to 300. This change was made to give you more flexibility when setting budget notifications.
* `service/cloudtrail`: Updates service documentation and paginators
* Doc-only update for AWSCloudTrail: Updated links/descriptions
* `aws/endpoints`: Updated Regions and Endpoints metadata.
* `service/opsworkscm`: Updates service API, documentation, and paginators
* OpsWorks for Chef Automate has added a new field "AssociatePublicIpAddress" to the CreateServer request, "CloudFormationStackArn" to the Server model and "TERMINATED" server state.
Release v1.7.3 (2017-02-28)
===
Service Client Updates
---
* `service/mturk`: Renaming service
* service/mechanicalturkrequesterservice was renamed to service/mturk. Be sure to change any references of the old client to the new.
Release v1.7.2 (2017-02-28)
===
Service Client Updates
---
* `service/dynamodb`: Updates service API and documentation
* Release notes: Time to Live (TTL) is a feature that allows you to define when items in a table expire and can be purged from the database, so that you don't have to track expired data and delete it manually. With TTL enabled on a DynamoDB table, you can set a timestamp for deletion on a per-item basis, allowing you to limit storage usage to only those records that are relevant.
* `service/iam`: Updates service API, documentation, and paginators
* This release adds support for AWS Organizations service control policies (SCPs) to SimulatePrincipalPolicy operation. If there are SCPs associated with the simulated user's account, their effect on the result is captured in the OrganizationDecisionDetail element in the EvaluationResult.
* `service/mechanicalturkrequesterservice`: Adds new service
* Amazon Mechanical Turk is a web service that provides an on-demand, scalable, human workforce to complete jobs that humans can do better than computers, for example, recognizing objects in photos.
* `service/organizations`: Adds new service
* AWS Organizations is a web service that enables you to consolidate your multiple AWS accounts into an organization and centrally manage your accounts and their resources.
* `service/dynamodbstreams`: Updates service API, documentation, and paginators
* `service/waf`: Updates service API, documentation, and paginators
* Aws WAF - For GetSampledRequests action, changed max number of samples from 100 to 500.
* `service/wafregional`: Updates service API, documentation, and paginators
Release v1.7.1 (2017-02-24)
===
Service Client Updates
---
* `service/elasticsearchservice`: Updates service API, documentation, paginators, and examples
* Added three new API calls to existing Amazon Elasticsearch service to expose Amazon Elasticsearch imposed limits to customers.
Release v1.7.0 (2017-02-23)
===
Service Client Updates
---
* `service/ec2`: Updates service API
* New EC2 I3 instance type
SDK Bug
---
* `service/s3/s3manager`: Adding support for SSE (#1097)
* Fixes SSE fields not being applied to a part during multi part upload.
SDK Feature
---
* `aws/session`: Add support for AssumeRoles with MFA (#1088)
* Adds support for assuming IAM roles with MFA enabled. A TokenProvider func was added to stscreds.AssumeRoleProvider that will be called each time the role's credentials need to be refreshed. A basic token provider that sources the MFA token from stdin as stscreds.StdinTokenProvider.
* `aws/session`: Update SDK examples and docs to use session.Must (#1099)
* Updates the SDK's example and docs to use session.Must where possible to highlight its usage as apposed to session error checking that is most cases errors will be terminal to the application anyways.
Release v1.6.27 (2017-02-22)
===
Service Client Updates
---
* `service/clouddirectory`: Updates service documentation
* ListObjectAttributes documentation updated based on forum feedback
* `service/elasticbeanstalk`: Updates service API, documentation, and paginators
* Elastic Beanstalk adds support for creating and managing custom platform.
* `service/gamelift`: Updates service API, documentation, and paginators
* Allow developers to configure global queues for creating GameSessions. Allow PlayerData on PlayerSessions to store player-specific data.
* `service/route53`: Updates service API, documentation, and examples
* Added support for operations CreateVPCAssociationAuthorization and DeleteVPCAssociationAuthorization to throw a ConcurrentModification error when a conflicting modification occurs in parallel to the authorizations in place for a given hosted zone.
Release v1.6.26 (2017-02-21)
===
Service Client Updates
---
* `service/ec2`: Updates service API and documentation
* Added the billingProduct parameter to the RegisterImage API.
Release v1.6.25 (2017-02-17)
===
Service Client Updates
---
* `service/directconnect`: Updates service API, documentation, and paginators
* This update will introduce the ability for Direct Connect customers to take advantage of Link Aggregation (LAG). This allows you to bundle many individual physical interfaces into a single logical interface, referred to as a LAG. This makes administration much simpler as the majority of configuration is done on the LAG while you are free to add or remove physical interfaces from the bundle as bandwidth demand increases or decreases. A concrete example of the simplification added by LAG is that customers need only a single BGP session as opposed to one session per physical connection.
Release v1.6.24 (2017-02-16)
===
Service Client Updates
---
* `service/cognitoidentity`: Updates service API, documentation, and paginators
* Allow createIdentityPool and updateIdentityPool API to set server side token check value on identity pool
* `service/configservice`: Updates service API and documentation
* AWS Config now supports a new test mode for the PutEvaluations API. Set the TestMode parameter to true in your custom rule to verify whether your AWS Lambda function will deliver evaluation results to AWS Config. No updates occur to your existing evaluations, and evaluation results are not sent to AWS Config.
Release v1.6.23 (2017-02-15)
===
Service Client Updates
---
* `service/kms`: Updates service API, documentation, paginators, and examples
* his release of AWS Key Management Service introduces the ability to tag keys. Tagging keys can help you organize your keys and track your KMS costs in the cost allocation report. This release also increases the maximum length of a key ID to accommodate ARNs that include a long key alias.
Release v1.6.22 (2017-02-14)
===
Service Client Updates
---
* `service/ec2`: Updates service API, documentation, and paginators
* Adds support for the new Modify Volumes apis.
Release v1.6.21 (2017-02-11)
===
Service Client Updates
---
* `service/storagegateway`: Updates service API, documentation, and paginators
* File gateway mode in AWS Storage gateway provides access to objects in S3 as files on a Network File System (NFS) mount point. This is done by creating Nfs file shares using existing APIs CreateNfsFileShare. Using the feature in this update, the customer can restrict the clients that have read/write access to the gateway by specifying the list of clients as a list of IP addresses or CIDR blocks. This list can be specified using the API CreateNfsFileShare while creating new file shares, or UpdateNfsFileShare while update existing file shares. To find out the list of clients that have access, the existing API DescribeNfsFileShare will now output the list of clients that have access.
Release v1.6.20 (2017-02-09)
===
Service Client Updates
---
* `service/ec2`: Updates service API and documentation
* This feature allows customers to associate an IAM profile to running instances that do not have any.
* `service/rekognition`: Updates service API and documentation
* DetectFaces and IndexFaces operations now return an estimate of the age of the face as an age range.
SDK Features
---
* `aws/endpoints`: Add option to resolve unknown endpoints (#1074)
Release v1.6.19 (2017-02-08)
===
Service Client Updates
---
* `aws/endpoints`: Updated Regions and Endpoints metadata.
* `service/glacier`: Updates service examples
* Doc Update
* `service/lexruntimeservice`: Adds new service
* Preview release
SDK Bug Fixes
---
* `private/protocol/json`: Fixes json to throw an error if a float number is (+/-)Inf and NaN (#1068)
* `private/model/api`: Fix documentation error listing (#1067)
SDK Features
---
* `private/model`: Add service response error code generation (#1061)
Release v1.6.18 (2017-01-27)
===
Service Client Updates
---
* `service/clouddirectory`: Adds new service
* Amazon Cloud Directory is a highly scalable, high performance, multi-tenant directory service in the cloud. Its web-based directories make it easy for you to organize and manage application resources such as users, groups, locations, devices, policies, and the rich relationships between them.
* `service/codedeploy`: Updates service API, documentation, and paginators
* This release of AWS CodeDeploy introduces support for blue/green deployments. In a blue/green deployment, the current set of instances in a deployment group is replaced by new instances that have the latest application revision installed on them. After traffic is rerouted behind a load balancer to the replacement instances, the original instances can be terminated automatically or kept running for other uses.
* `service/ec2`: Updates service API and documentation
* Adds instance health check functionality to replace unhealthy EC2 Spot fleet instances with fresh ones.
* `service/rds`: Updates service API and documentation
* Snapshot Engine Version Upgrade
Release v1.6.17 (2017-01-25)
===
Service Client Updates
---
* `service/elbv2`: Updates service API, documentation, and paginators
* Application Load Balancers now support native Internet Protocol version 6 (IPv6) in an Amazon Virtual Private Cloud (VPC). With this ability, clients can now connect to the Application Load Balancer in a dual-stack mode via either IPv4 or IPv6.
* `service/rds`: Updates service API and documentation
* Cross Region Read Replica Copying (CreateDBInstanceReadReplica)
Release v1.6.16 (2017-01-24)
===
Service Client Updates
---
* `service/codebuild`: Updates service documentation and paginators
* Documentation updates
* `service/codecommit`: Updates service API, documentation, and paginators
* AWS CodeCommit now includes the option to view the differences between a commit and its parent commit from within the console. You can view the differences inline (Unified view) or side by side (Split view). To view information about the differences between a commit and something other than its parent, you can use the AWS CLI and the get-differences and get-blob commands, or you can use the GetDifferences and GetBlob APIs.
* `service/ecs`: Updates service API and documentation
* Amazon ECS now supports a state for container instances that can be used to drain a container instance in preparation for maintenance or cluster scale down.
Release v1.6.15 (2017-01-20)
===
Service Client Updates
---
* `service/acm`: Updates service API, documentation, and paginators
* Update for AWS Certificate Manager: Updated response elements for DescribeCertificate API in support of managed renewal
* `service/health`: Updates service documentation
Release v1.6.14 (2017-01-19)
===
Service Client Updates
---
* `service/ec2`: Updates service API, documentation, and paginators
* Amazon EC2 Spot instances now support dedicated tenancy, providing the ability to run Spot instances single-tenant manner on physically isolated hardware within a VPC to satisfy security, privacy, or other compliance requirements. Dedicated Spot instances can be requested using RequestSpotInstances and RequestSpotFleet.
Release v1.6.13 (2017-01-18)
===
Service Client Updates
---
* `service/rds`: Updates service API, documentation, and paginators
Release v1.6.12 (2017-01-17)
===
Service Client Updates
---
* `service/dynamodb`: Updates service API, documentation, and paginators
* Tagging Support for Amazon DynamoDB Tables and Indexes
* `aws/endpoints`: Updated Regions and Endpoints metadata.
* `service/glacier`: Updates service API, paginators, and examples
* Doc-only Update for Glacier: Added code snippets
* `service/polly`: Updates service documentation and examples
* Doc-only update for Amazon Polly -- added snippets
* `service/rekognition`: Updates service documentation and paginators
* Added code samples to Rekognition reference topics.
* `service/route53`: Updates service API and paginators
* Add ca-central-1 and eu-west-2 enum values to CloudWatchRegion enum
Release v1.6.11 (2017-01-16)
===
Service Client Updates
---
* `service/configservice`: Updates service API, documentation, and paginators
* `service/costandusagereportservice`: Adds new service
* The AWS Cost and Usage Report Service API allows you to enable and disable the Cost & Usage report, as well as modify the report name, the data granularity, and the delivery preferences.
* `service/dynamodb`: Updates service API, documentation, and examples
* Snippets for the DynamoDB API.
* `service/elasticache`: Updates service API, documentation, and examples
* Adds new code examples.
* `aws/endpoints`: Updated Regions and Endpoints metadata.
Release v1.6.10 (2017-01-04)
===
Service Client Updates
---
* `service/configservice`: Updates service API and documentation
* AWSConfig is planning to add support for OversizedConfigurationItemChangeNotification message type in putConfigRule. After this release customers can use/write rules based on OversizedConfigurationItemChangeNotification mesage type.
* `service/efs`: Updates service API, documentation, and examples
* Doc-only Update for EFS: Added code snippets
* `service/iam`: Updates service documentation and examples
* `service/lambda`: Updates service documentation and examples
* Doc only updates for Lambda: Added code snippets
* `service/marketplacecommerceanalytics`: Updates service API and documentation
* Added support for data set disbursed_amount_by_instance_hours, with historical data available starting 2012-09-04. New data is published to this data set every 30 days.
* `service/rds`: Updates service documentation
* Updated documentation for CopyDBSnapshot.
* `service/rekognition`: Updates service documentation and examples
* Doc-only Update for Rekognition: Added code snippets
* `service/snowball`: Updates service examples
* `service/dynamodbstreams`: Updates service API and examples
* Doc-only Update for DynamoDB Streams: Added code snippets
SDK Feature
---
* `private/model/api`: Increasing the readability of code generated files. (#1024)
Release v1.6.9 (2016-12-30)
===
Service Client Updates
---
* `service/codedeploy`: Updates service API and documentation
* CodeDeploy will support Iam Session Arns in addition to Iam User Arns for on premise host authentication.
* `service/ecs`: Updates service API and documentation
* Amazon EC2 Container Service (ECS) now supports the ability to customize the placement of tasks on container instances.
* `aws/endpoints`: Updated Regions and Endpoints metadata.
Release v1.6.8 (2016-12-22)
===
Service Client Updates
---
* `service/apigateway`: Updates service API and documentation
* Amazon API Gateway is adding support for generating SDKs in more languages. This update introduces two new operations used to dynamically discover these SDK types and what configuration each type accepts.
* `service/directoryservice`: Updates service documentation
* Added code snippets for the DS SDKs
* `service/elasticbeanstalk`: Updates service API and documentation
* `service/iam`: Updates service API and documentation
* Adds service-specific credentials to IAM service to make it easier to onboard CodeCommit customers. These are username/password credentials that work with a single service.
* `service/kms`: Updates service API, documentation, and examples
* Update docs and add SDK examples
Release v1.6.7 (2016-12-22)
===
Service Client Updates
---
* `service/ecr`: Updates service API and documentation
* `aws/endpoints`: Updated Regions and Endpoints metadata.
* `service/rds`: Updates service API and documentation
* Cross Region Encrypted Snapshot Copying (CopyDBSnapshot)
Release v1.6.6 (2016-12-20)
===
Service Client Updates
---
* `aws/endpoints`: Updated Regions and Endpoints metadata.
* `service/firehose`: Updates service API, documentation, and examples
* Processing feature enables users to process and modify records before Amazon Firehose delivers them to destinations.
* `service/route53`: Updates service API and documentation
* Enum updates for eu-west-2 and ca-central-1
* `service/storagegateway`: Updates service API, documentation, and examples
* File gateway is a new mode in the AWS Storage Gateway that support a file interface into S3, alongside the current block-based volume and VTL storage. File gateway combines a service and virtual software appliance, enabling you to store and retrieve objects in Amazon S3 using industry standard file protocols such as NFS. The software appliance, or gateway, is deployed into your on-premises environment as a virtual machine (VM) running on VMware ESXi. The gateway provides access to objects in S3 as files on a Network File System (NFS) mount point.
Release v1.6.5 (2016-12-19)
===
Service Client Updates
---
* `service/cloudformation`: Updates service documentation
* Minor doc update for CloudFormation.
* `service/cloudtrail`: Updates service paginators
* `service/cognitoidentity`: Updates service API and documentation
* We are adding Groups to Cognito user pools. Developers can perform CRUD operations on groups, add and remove users from groups, list users in groups, etc. We are adding fine-grained role-based access control for Cognito identity pools. Developers can configure an identity pool to get the IAM role from an authenticated user's token, or they can configure rules that will map a user to a different role
* `service/applicationdiscoveryservice`: Updates service API and documentation
* Adds new APIs to group discovered servers into Applications with get summary and neighbors. Includes additional filters for ListConfigurations and DescribeAgents API.
* `service/inspector`: Updates service API, documentation, and examples
* Doc-only Update for Inspector: Adding SDK code snippets for Inspector
* `service/sqs`: Updates service documentation
SDK Bug Fixes
---
* `aws/request`: Add PriorRequestNotComplete to throttle retry codes (#1011)
* Fixes: Not retrying when PriorRequestNotComplete #1009
SDK Feature
---
* `private/model/api`: Adds crosslinking to service documentation (#1010)
Release v1.6.4 (2016-12-15)
===
Service Client Updates
---
* `service/cognitoidentityprovider`: Updates service API and documentation
* `aws/endpoints`: Updated Regions and Endpoints metadata.
* `service/ssm`: Updates service API and documentation
* This will provide customers with access to the Patch Baseline and Patch Compliance APIs.
SDK Bug Fixes
---
* `service/route53`: Fix URL path cleaning for Route53 API requests (#1006)
* Fixes: SerializationError when using Route53 ChangeResourceRecordSets #1005
* `aws/request`: Add PriorRequestNotComplete to throttle retry codes (#1002)
* Fixes: Not retrying when PriorRequestNotComplete #1001
Release v1.6.3 (2016-12-14)
===
Service Client Updates
---
* `service/batch`: Adds new service
* AWS Batch is a batch computing service that lets customers define queues and compute environments and then submit work as batch jobs.
* `service/databasemigrationservice`: Updates service API and documentation
* Adds support for SSL enabled Oracle endpoints and task modification.
* `service/elasticbeanstalk`: Updates service documentation
* `aws/endpoints`: Updated Regions and Endpoints metadata.
* `service/cloudwatchlogs`: Updates service API and documentation
* Add support for associating LogGroups with AWSTagris tags
* `service/marketplacecommerceanalytics`: Updates service API and documentation
* Add new enum to DataSetType: sales_compensation_billed_revenue
* `service/rds`: Updates service documentation
* Doc-only Update for RDS: New versions available in CreateDBInstance
* `service/sts`: Updates service documentation
* Adding Code Snippet Examples for SDKs for STS
SDK Bug Fixes
---
* `aws/request`: Fix retrying timeout requests (#981)
* Fixes: Requests Retrying is broken if the error was caused due to a client timeout #947
* `aws/request`: Fix for Go 1.8 request incorrectly sent with body (#991)
* Fixes: service/route53: ListHostedZones hangs and then fails with go1.8 #984
* private/protocol/rest: Use RawPath instead of Opaque (#993)
* Fixes: HTTP2 request failing with REST protocol services, e.g AWS X-Ray
* private/model/api: Generate REST-JSON JSONVersion correctly (#998)
* Fixes: REST-JSON protocol service code missing JSONVersion metadata.
Release v1.6.2 (2016-12-08)
===
Service Client Updates
---
* `service/cloudfront`: Add lambda function associations to cache behaviors
* `service/codepipeline`: This is a doc-only update request to incorporate some recent minor revisions to the doc content.
* `service/rds`: Updates service API and documentation
* `service/wafregional`: With this new feature, customers can use AWS WAF directly on Application Load Balancers in a VPC within available regions to protect their websites and web services from malicious attacks such as SQL injection, Cross Site Scripting, bad bots, etc.
Release v1.6.1 (2016-12-07)
===
Service Client Updates
---
* `service/config`: Updates service API
* `service/s3`: Updates service API
* `service/sqs`: Updates service API and documentation
Release v1.6.0 (2016-12-06)
===
Service Client Updates
---
* `service/config`: Updates service API and documentation
* `service/ec2`: Updates service API
* `service/sts`: Updates service API, documentation, and examples
SDK Bug Fixes
---
* private/protocol/xml/xmlutil: Fix SDK XML unmarshaler #975
* Fixes GetBucketACL Grantee required type always nil. #916
SDK Feature
---
* aws/endpoints: Add endpoint metadata to SDK #961
* Adds Region and Endpoint metadata to the SDK. This allows you to enumerate regions and endpoint metadata based on a defined model embedded in the SDK.
Release v1.5.13 (2016-12-01)
===
Service Client Updates
---
* `service/apigateway`: Updates service API and documentation
* `service/appstream`: Adds new service
* `service/codebuild`: Adds new service
* `service/directconnect`: Updates service API and documentation
* `service/ec2`: Adds new service
* `service/elasticbeanstalk`: Updates service API and documentation
* `service/health`: Adds new service
* `service/lambda`: Updates service API and documentation
* `service/opsworkscm`: Adds new service
* `service/pinpoint`: Adds new service
* `service/shield`: Adds new service
* `service/ssm`: Updates service API and documentation
* `service/states`: Adds new service
* `service/xray`: Adds new service
Release v1.5.12 (2016-11-30)
===
Service Client Updates
---
* `service/lightsail`: Adds new service
* `service/polly`: Adds new service
* `service/rekognition`: Adds new service
* `service/snowball`: Updates service API and documentation
Release v1.5.11 (2016-11-29)
===
Service Client Updates
---
`service/s3`: Updates service API and documentation
Release v1.5.10 (2016-11-22)
===
Service Client Updates
---
* `service/cloudformation`: Updates service API and documentation
* `service/glacier`: Updates service API, documentation, and examples
* `service/route53`: Updates service API and documentation
* `service/s3`: Updates service API and documentation
SDK Bug Fixes
---
* `private/protocol/xml/xmlutil`: Fixes xml marshaler to unmarshal properly
into tagged fields
[#916](https://github.com/aws/aws-sdk-go/issues/916)
Release v1.5.9 (2016-11-22)
===
Service Client Updates
---
* `service/cloudtrail`: Updates service API and documentation
* `service/ecs`: Updates service API and documentation
Release v1.5.8 (2016-11-18)
===
Service Client Updates
---
* `service/application-autoscaling`: Updates service API and documentation
* `service/elasticmapreduce`: Updates service API and documentation
* `service/elastictranscoder`: Updates service API, documentation, and examples
* `service/gamelift`: Updates service API and documentation
* `service/lambda`: Updates service API and documentation
Release v1.5.7 (2016-11-18)
===
Service Client Updates
---
* `service/apigateway`: Updates service API and documentation
* `service/meteringmarketplace`: Updates service API and documentation
* `service/monitoring`: Updates service API and documentation
* `service/sqs`: Updates service API, documentation, and examples
Release v1.5.6 (2016-11-16)
===
Service Client Updates
---
`service/route53`: Updates service API and documentation
`service/servicecatalog`: Updates service API and documentation
Release v1.5.5 (2016-11-15)
===
Service Client Updates
---
* `service/ds`: Updates service API and documentation
* `service/elasticache`: Updates service API and documentation
* `service/kinesis`: Updates service API and documentation
Release v1.5.4 (2016-11-15)
===
Service Client Updates
---
* `service/cognito-idp`: Updates service API and documentation
Release v1.5.3 (2016-11-11)
===
Service Client Updates
---
* `service/cloudformation`: Updates service documentation and examples
* `service/logs`: Updates service API and documentation
Release v1.5.2 (2016-11-03)
===
Service Client Updates
---
* `service/directconnect`: Updates service API and documentation
Release v1.5.1 (2016-11-02)
===
Service Client Updates
---
* `service/email`: Updates service API and documentation
Release v1.5.0 (2016-11-01)
===
Service Client Updates
---
* `service/cloudformation`: Updates service API and documentation
* `service/ecr`: Updates service paginators
SDK Feature Updates
---
* `private/model/api`: Add generated setters for API parameters (#918)
* Adds setters to the SDK's API parameter types, and are a convenience method that reduce the need to use `aws.String` and like utility.
Release v1.4.22 (2016-10-25)
===
Service Client Updates
---
* `service/elasticloadbalancingv2`: Updates service documentation.
* `service/autoscaling`: Updates service documentation.
Release v1.4.21 (2016-10-24)
===
Service Client Updates
---
* `service/sms`: AWS Server Migration Service (SMS) is an agentless service which makes it easier and faster for you to migrate thousands of on-premises workloads to AWS. AWS SMS allows you to automate, schedule, and track incremental replications of live server volumes, making it easier for you to coordinate large-scale server migrations.
* `service/ecs`: Updates documentation.
SDK Feature Updates
---
* `private/models/api`: Improve code generation of documentation.
Release v1.4.20 (2016-10-20)
===
Service Client Updates
---
* `service/budgets`: Adds new service, AWS Budgets.
* `service/waf`: Updates service documentation.
Release v1.4.19 (2016-10-18)
===
Service Client Updates
---
* `service/cloudfront`: Updates service API and documentation.
* Ability to use Amazon CloudFront to deliver your content both via IPv6 and IPv4 using HTTP/HTTPS.
* `service/configservice`: Update service API and documentation.
* `service/iot`: Updates service API and documentation.
* `service/kinesisanalytics`: Updates service API and documentation.
* Whenever Amazon Kinesis Analytics is not able to detect schema for the given streaming source on DiscoverInputSchema API, we would return the raw records that was sampled to detect the schema.
* `service/rds`: Updates service API and documentation.
* Amazon Aurora integrates with other AWS services to allow you to extend your Aurora DB cluster to utilize other capabilities in the AWS cloud. Permission to access other AWS services is granted by creating an IAM role with the necessary permissions, and then associating the role with your DB cluster.
SDK Feature Updates
---
* `service/dynamodb/dynamodbattribute`: Add UnmarshalListOfMaps #897
* Adds support for unmarshaling a list of maps. This is useful for unmarshaling the DynamoDB AttributeValue list of maps returned by APIs like Query and Scan.
Release v1.4.18 (2016-10-17)
===
Service Model Updates
---
* `service/route53`: Updates service API and documentation.
Release v1.4.17
===
Service Model Updates
---
* `service/acm`: Update service API, and documentation.
* This change allows users to import third-party SSL/TLS certificates into ACM.
* `service/elasticbeanstalk`: Update service API, documentation, and pagination.
* Elastic Beanstalk DescribeApplicationVersions API is being updated to support pagination.
* `service/gamelift`: Update service API, and documentation.
* New APIs to protect game developer resource (builds, alias, fleets, instances, game sessions and player sessions) against abuse.
SDK Features
---
* `service/s3`: Add support for accelerate with dualstack [#887](https://github.com/aws/aws-sdk-go/issues/887)
Release v1.4.16 (2016-10-13)
===
Service Model Updates
---
* `service/ecr`: Update Amazon EC2 Container Registry service model
* DescribeImages is a new api used to expose image metadata which today includes image size and image creation timestamp.
* `service/elasticache`: Update Amazon ElastiCache service model
* Elasticache is launching a new major engine release of Redis, 3.2 (providing stability updates and new command sets over 2.8), as well as ElasticSupport for enabling Redis Cluster in 3.2, which provides support for multiple node groups to horizontally scale data, as well as superior engine failover capabilities
SDK Bug Fixes
---
* `aws/session`: Skip shared config on read errors [#883](https://github.com/aws/aws-sdk-go/issues/883)
* `aws/signer/v4`: Add support for URL.EscapedPath to signer [#885](https://github.com/aws/aws-sdk-go/issues/885)
SDK Features
---
* `private/model/api`: Add docs for errors to API operations [#881](https://github.com/aws/aws-sdk-go/issues/881)
* `private/model/api`: Improve field and waiter doc strings [#879](https://github.com/aws/aws-sdk-go/issues/879)
* `service/dynamodb/dynamodbattribute`: Allow multiple struct tag elements [#886](https://github.com/aws/aws-sdk-go/issues/886)
* Add build tags to internal SDK tools [#880](https://github.com/aws/aws-sdk-go/issues/880)
Release v1.4.15 (2016-10-06)
===
Service Model Updates
---
* `service/cognitoidentityprovider`: Update Amazon Cognito Identity Provider service model
* `service/devicefarm`: Update AWS Device Farm documentation
* `service/opsworks`: Update AWS OpsWorks service model
* `service/s3`: Update Amazon Simple Storage Service model
* `service/waf`: Update AWS WAF service model
SDK Bug Fixes
---
* `aws/request`: Fix HTTP Request Body race condition [#874](https://github.com/aws/aws-sdk-go/issues/874)
SDK Feature Updates
---
* `aws/ec2metadata`: Add support for EC2 User Data [#872](https://github.com/aws/aws-sdk-go/issues/872)
* `aws/signer/v4`: Remove logic determining if request needs to be resigned [#876](https://github.com/aws/aws-sdk-go/issues/876)
Release v1.4.14 (2016-09-29)
===
* `service/ec2`: api, documentation, and paginators updates.
* `service/s3`: api and documentation updates.
Release v1.4.13 (2016-09-27)
===
* `service/codepipeline`: documentation updates.
* `service/cloudformation`: api and documentation updates.
* `service/kms`: documentation updates.
* `service/elasticfilesystem`: documentation updates.
* `service/snowball`: documentation updates.

View File

122
vendor/github.com/aws/aws-sdk-go/CONTRIBUTING.md generated vendored Normal file
View File

@@ -0,0 +1,122 @@
Contributing to the AWS SDK for Go
We work hard to provide a high-quality and useful SDK, and we greatly value
feedback and contributions from our community. Whether it's a bug report,
new feature, correction, or additional documentation, we welcome your issues
and pull requests. Please read through this document before submitting any
issues or pull requests to ensure we have all the necessary information to
effectively respond to your bug report or contribution.
## Filing Bug Reports
You can file bug reports against the SDK on the [GitHub issues][issues] page.
If you are filing a report for a bug or regression in the SDK, it's extremely
helpful to provide as much information as possible when opening the original
issue. This helps us reproduce and investigate the possible bug without having
to wait for this extra information to be provided. Please read the following
guidelines prior to filing a bug report.
1. Search through existing [issues][] to ensure that your specific issue has
not yet been reported. If it is a common issue, it is likely there is
already a bug report for your problem.
2. Ensure that you have tested the latest version of the SDK. Although you
may have an issue against an older version of the SDK, we cannot provide
bug fixes for old versions. It's also possible that the bug may have been
fixed in the latest release.
3. Provide as much information about your environment, SDK version, and
relevant dependencies as possible. For example, let us know what version
of Go you are using, which and version of the operating system, and the
the environment your code is running in. e.g Container.
4. Provide a minimal test case that reproduces your issue or any error
information you related to your problem. We can provide feedback much
more quickly if we know what operations you are calling in the SDK. If
you cannot provide a full test case, provide as much code as you can
to help us diagnose the problem. Any relevant information should be provided
as well, like whether this is a persistent issue, or if it only occurs
some of the time.
## Submitting Pull Requests
We are always happy to receive code and documentation contributions to the SDK.
Please be aware of the following notes prior to opening a pull request:
1. The SDK is released under the [Apache license][license]. Any code you submit
will be released under that license. For substantial contributions, we may
ask you to sign a [Contributor License Agreement (CLA)][cla].
2. If you would like to implement support for a significant feature that is not
yet available in the SDK, please talk to us beforehand to avoid any
duplication of effort.
3. Wherever possible, pull requests should contain tests as appropriate.
Bugfixes should contain tests that exercise the corrected behavior (i.e., the
test should fail without the bugfix and pass with it), and new features
should be accompanied by tests exercising the feature.
4. Pull requests that contain failing tests will not be merged until the test
failures are addressed. Pull requests that cause a significant drop in the
SDK's test coverage percentage are unlikely to be merged until tests have
been added.
### Testing
To run the tests locally, running the `make unit` command will `go get` the
SDK's testing dependencies, and run vet, link and unit tests for the SDK.
```
make unit
```
Standard go testing functionality is supported as well. To test SDK code that
is tagged with `codegen` you'll need to set the build tag in the go test
command. The `make unit` command will do this automatically.
```
go test -tags codegen ./private/...
```
See the `Makefile` for additional testing tags that can be used in testing.
To test on multiple platform the SDK includes several DockerFiles under the
`awstesting/sandbox` folder, and associated make recipes to to execute
unit testing within environments configured for specific Go versions.
```
make sandbox-test-go18
```
To run all sandbox environments use the following make recipe
```
# Optionally update the Go tip that will be used during the batch testing
make update-aws-golang-tip
# Run all SDK tests for supported Go versions in sandboxes
make sandbox-test
```
In addition the sandbox environment include make recipes for interactive modes
so you can run command within the Docker container and context of the SDK.
```
make sandbox-go18
```
### Changelog
You can see all release changes in the `CHANGELOG.md` file at the root of the
repository. The release notes added to this file will contain service client
updates, and major SDK changes.
[issues]: https://github.com/aws/aws-sdk-go/issues
[pr]: https://github.com/aws/aws-sdk-go/pulls
[license]: http://aws.amazon.com/apache2.0/
[cla]: http://en.wikipedia.org/wiki/Contributor_License_Agreement
[releasenotes]: https://github.com/aws/aws-sdk-go/releases

202
vendor/github.com/aws/aws-sdk-go/LICENSE.txt generated vendored Normal file
View File

@@ -0,0 +1,202 @@
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.

175
vendor/github.com/aws/aws-sdk-go/Makefile generated vendored Normal file
View File

@@ -0,0 +1,175 @@
LINTIGNOREDOT='awstesting/integration.+should not use dot imports'
LINTIGNOREDOC='service/[^/]+/(api|service|waiters)\.go:.+(comment on exported|should have comment or be unexported)'
LINTIGNORECONST='service/[^/]+/(api|service|waiters)\.go:.+(type|struct field|const|func) ([^ ]+) should be ([^ ]+)'
LINTIGNORESTUTTER='service/[^/]+/(api|service)\.go:.+(and that stutters)'
LINTIGNOREINFLECT='service/[^/]+/(api|errors|service)\.go:.+(method|const) .+ should be '
LINTIGNOREINFLECTS3UPLOAD='service/s3/s3manager/upload\.go:.+struct field SSEKMSKeyId should be '
LINTIGNOREDEPS='vendor/.+\.go'
UNIT_TEST_TAGS="example codegen"
SDK_WITH_VENDOR_PKGS=$(shell go list -tags ${UNIT_TEST_TAGS} ./... | grep -v "/vendor/src")
SDK_ONLY_PKGS=$(shell go list ./... | grep -v "/vendor/")
SDK_UNIT_TEST_ONLY_PKGS=$(shell go list -tags ${UNIT_TEST_TAGS} ./... | grep -v "/vendor/")
SDK_GO_1_4=$(shell go version | grep "go1.4")
SDK_GO_1_5=$(shell go version | grep "go1.5")
SDK_GO_VERSION=$(shell go version | awk '''{print $$3}''' | tr -d '''\n''')
all: get-deps generate unit
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " api_info to print a list of services and versions"
@echo " docs to build SDK documentation"
@echo " build to go build the SDK"
@echo " unit to run unit tests"
@echo " integration to run integration tests"
@echo " performance to run performance tests"
@echo " verify to verify tests"
@echo " lint to lint the SDK"
@echo " vet to vet the SDK"
@echo " generate to go generate and make services"
@echo " gen-test to generate protocol tests"
@echo " gen-services to generate services"
@echo " get-deps to go get the SDK dependencies"
@echo " get-deps-tests to get the SDK's test dependencies"
@echo " get-deps-verify to get the SDK's verification dependencies"
generate: gen-test gen-endpoints gen-services
gen-test: gen-protocol-test
gen-services:
go generate ./service
gen-protocol-test:
go generate ./private/protocol/...
gen-endpoints:
go generate ./models/endpoints/
build:
@echo "go build SDK and vendor packages"
@go build ${SDK_ONLY_PKGS}
unit: get-deps-tests build verify
@echo "go test SDK and vendor packages"
@go test -tags ${UNIT_TEST_TAGS} $(SDK_UNIT_TEST_ONLY_PKGS)
unit-with-race-cover: get-deps-tests build verify
@echo "go test SDK and vendor packages"
@go test -tags ${UNIT_TEST_TAGS} -race -cpu=1,2,4 $(SDK_UNIT_TEST_ONLY_PKGS)
integration: get-deps-tests integ-custom smoke-tests performance
integ-custom:
go test -tags "integration" ./awstesting/integration/customizations/...
smoke-tests: get-deps-tests
gucumber -go-tags "integration" ./awstesting/integration/smoke
performance: get-deps-tests
AWS_TESTING_LOG_RESULTS=${log-detailed} AWS_TESTING_REGION=$(region) AWS_TESTING_DB_TABLE=$(table) gucumber -go-tags "integration" ./awstesting/performance
sandbox-tests: sandbox-test-go15 sandbox-test-go15-novendorexp sandbox-test-go16 sandbox-test-go17 sandbox-test-go18 sandbox-test-gotip
sandbox-build-go15:
docker build -f ./awstesting/sandbox/Dockerfile.test.go1.5 -t "aws-sdk-go-1.5" .
sandbox-go15: sandbox-build-go15
docker run -i -t aws-sdk-go-1.5 bash
sandbox-test-go15: sandbox-build-go15
docker run -t aws-sdk-go-1.5
sandbox-build-go15-novendorexp:
docker build -f ./awstesting/sandbox/Dockerfile.test.go1.5-novendorexp -t "aws-sdk-go-1.5-novendorexp" .
sandbox-go15-novendorexp: sandbox-build-go15-novendorexp
docker run -i -t aws-sdk-go-1.5-novendorexp bash
sandbox-test-go15-novendorexp: sandbox-build-go15-novendorexp
docker run -t aws-sdk-go-1.5-novendorexp
sandbox-build-go16:
docker build -f ./awstesting/sandbox/Dockerfile.test.go1.6 -t "aws-sdk-go-1.6" .
sandbox-go16: sandbox-build-go16
docker run -i -t aws-sdk-go-1.6 bash
sandbox-test-go16: sandbox-build-go16
docker run -t aws-sdk-go-1.6
sandbox-build-go17:
docker build -f ./awstesting/sandbox/Dockerfile.test.go1.7 -t "aws-sdk-go-1.7" .
sandbox-go17: sandbox-build-go17
docker run -i -t aws-sdk-go-1.7 bash
sandbox-test-go17: sandbox-build-go17
docker run -t aws-sdk-go-1.7
sandbox-build-go18:
docker build -f ./awstesting/sandbox/Dockerfile.test.go1.8 -t "aws-sdk-go-1.8" .
sandbox-go18: sandbox-build-go18
docker run -i -t aws-sdk-go-1.8 bash
sandbox-test-go18: sandbox-build-go18
docker run -t aws-sdk-go-1.8
sandbox-build-gotip:
@echo "Run make update-aws-golang-tip, if this test fails because missing aws-golang:tip container"
docker build -f ./awstesting/sandbox/Dockerfile.test.gotip -t "aws-sdk-go-tip" .
sandbox-gotip: sandbox-build-gotip
docker run -i -t aws-sdk-go-tip bash
sandbox-test-gotip: sandbox-build-gotip
docker run -t aws-sdk-go-tip
update-aws-golang-tip:
docker build --no-cache=true -f ./awstesting/sandbox/Dockerfile.golang-tip -t "aws-golang:tip" .
verify: get-deps-verify lint vet
lint:
@echo "go lint SDK and vendor packages"
@lint=`if [ \( -z "${SDK_GO_1_4}" \) -a \( -z "${SDK_GO_1_5}" \) ]; then golint ./...; else echo "skipping golint"; fi`; \
lint=`echo "$$lint" | grep -E -v -e ${LINTIGNOREDOT} -e ${LINTIGNOREDOC} -e ${LINTIGNORECONST} -e ${LINTIGNORESTUTTER} -e ${LINTIGNOREINFLECT} -e ${LINTIGNOREDEPS} -e ${LINTIGNOREINFLECTS3UPLOAD}`; \
echo "$$lint"; \
if [ "$$lint" != "" ] && [ "$$lint" != "skipping golint" ]; then exit 1; fi
SDK_BASE_FOLDERS=$(shell ls -d */ | grep -v vendor | grep -v awsmigrate)
ifneq (,$(findstring go1.4, ${SDK_GO_VERSION}))
GO_VET_CMD=echo skipping go vet, ${SDK_GO_VERSION}
else ifneq (,$(findstring go1.6, ${SDK_GO_VERSION}))
GO_VET_CMD=go tool vet --all -shadow -example=false
else
GO_VET_CMD=go tool vet --all -shadow
endif
vet:
${GO_VET_CMD} ${SDK_BASE_FOLDERS}
get-deps: get-deps-tests get-deps-verify
@echo "go get SDK dependencies"
@go get -v $(SDK_ONLY_PKGS)
get-deps-tests:
@echo "go get SDK testing dependencies"
go get github.com/gucumber/gucumber/cmd/gucumber
go get github.com/stretchr/testify
go get github.com/smartystreets/goconvey
go get golang.org/x/net/html
get-deps-verify:
@echo "go get SDK verification utilities"
@if [ \( -z "${SDK_GO_1_4}" \) -a \( -z "${SDK_GO_1_5}" \) ]; then go get github.com/golang/lint/golint; else echo "skipped getting golint"; fi
bench:
@echo "go bench SDK packages"
@go test -run NONE -bench . -benchmem -tags 'bench' $(SDK_ONLY_PKGS)
bench-protocol:
@echo "go bench SDK protocol marshallers"
@go test -run NONE -bench . -benchmem -tags 'bench' ./private/protocol/...
docs:
@echo "generate SDK docs"
@# This env variable, DOCS, is for internal use
@if [ -z ${AWS_DOC_GEN_TOOL} ]; then\
rm -rf doc && bundle install && bundle exec yard;\
else\
$(AWS_DOC_GEN_TOOL) `pwd`;\
fi
api_info:
@go run private/model/cli/api-info/api-info.go

3
vendor/github.com/aws/aws-sdk-go/NOTICE.txt generated vendored Normal file
View File

@@ -0,0 +1,3 @@
AWS SDK for Go
Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
Copyright 2014-2015 Stripe, Inc.

134
vendor/github.com/aws/aws-sdk-go/README.md generated vendored Normal file
View File

@@ -0,0 +1,134 @@
# AWS SDK for Go
[![API Reference](http://img.shields.io/badge/api-reference-blue.svg)](http://docs.aws.amazon.com/sdk-for-go/api)
[![Join the chat at https://gitter.im/aws/aws-sdk-go](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/aws/aws-sdk-go?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Build Status](https://img.shields.io/travis/aws/aws-sdk-go.svg)](https://travis-ci.org/aws/aws-sdk-go)
[![Apache V2 License](http://img.shields.io/badge/license-Apache%20V2-blue.svg)](https://github.com/aws/aws-sdk-go/blob/master/LICENSE.txt)
aws-sdk-go is the official AWS SDK for the Go programming language.
Checkout our [release notes](https://github.com/aws/aws-sdk-go/releases) for information about the latest bug fixes, updates, and features added to the SDK.
## Installing
If you are using Go 1.5 with the `GO15VENDOREXPERIMENT=1` vendoring flag, or 1.6 and higher you can use the following command to retrieve the SDK. The SDK's non-testing dependencies will be included and are vendored in the `vendor` folder.
go get -u github.com/aws/aws-sdk-go
Otherwise if your Go environment does not have vendoring support enabled, or you do not want to include the vendored SDK's dependencies you can use the following command to retrieve the SDK and its non-testing dependencies using `go get`.
go get -u github.com/aws/aws-sdk-go/aws/...
go get -u github.com/aws/aws-sdk-go/service/...
If you're looking to retrieve just the SDK without any dependencies use the following command.
go get -d github.com/aws/aws-sdk-go/
These two processes will still include the `vendor` folder and it should be deleted if its not going to be used by your environment.
rm -rf $GOPATH/src/github.com/aws/aws-sdk-go/vendor
## Getting Help
Please use these community resources for getting help. We use the GitHub issues for tracking bugs and feature requests.
* Ask a question on [StackOverflow](http://stackoverflow.com/) and tag it with the [`aws-sdk-go`](http://stackoverflow.com/questions/tagged/aws-sdk-go) tag.
* Come join the AWS SDK for Go community chat on [gitter](https://gitter.im/aws/aws-sdk-go).
* Open a support ticket with [AWS Support](http://docs.aws.amazon.com/awssupport/latest/user/getting-started.html).
* If you think you may of found a bug, please open an [issue](https://github.com/aws/aws-sdk-go/issues/new).
## Opening Issues
If you encounter a bug with the AWS SDK for Go we would like to hear about it. Search the [existing issues]( https://github.com/aws/aws-sdk-go/issues) and see if others are also experiencing the issue before opening a new issue. Please include the version of AWS SDK for Go, Go language, and OS youre using. Please also include repro case when appropriate.
The GitHub issues are intended for bug reports and feature requests. For help and questions with using AWS SDK for GO please make use of the resources listed in the [Getting Help]( https://github.com/aws/aws-sdk-go#getting-help) section. Keeping the list of open issues lean will help us respond in a timely manner.
## Reference Documentation
[`Getting Started Guide`](https://aws.amazon.com/sdk-for-go/) - This document is a general introduction how to configure and make requests with the SDK. If this is your first time using the SDK, this documentation and the API documentation will help you get started. This document focuses on the syntax and behavior of the SDK. The [Service Developer Guide](https://aws.amazon.com/documentation/) will help you get started using specific AWS services.
[`SDK API Reference Documentation`](https://docs.aws.amazon.com/sdk-for-go/api/) - Use this document to look up all API operation input and output parameters for AWS services supported by the SDK. The API reference also includes documentation of the SDK, and examples how to using the SDK, service client API operations, and API operation require parameters.
[`Service Developer Guide`](https://aws.amazon.com/documentation/) - Use this documentation to learn how to interface with an AWS service. These are great guides both, if you're getting started with a service, or looking for more information on a service. You should not need this document for coding, though in some cases, services may supply helpful samples that you might want to look out for.
[`SDK Examples`](https://github.com/aws/aws-sdk-go/tree/master/example) - Included in the SDK's repo are a several hand crafted examples using the SDK features and AWS services.
## Configuring Credentials
Before using the SDK, ensure that you've configured credentials. The best
way to configure credentials on a development machine is to use the
`~/.aws/credentials` file, which might look like:
```
[default]
aws_access_key_id = AKID1234567890
aws_secret_access_key = MY-SECRET-KEY
```
You can learn more about the credentials file from this
[blog post](http://blogs.aws.amazon.com/security/post/Tx3D6U6WSFGOK2H/A-New-and-Standardized-Way-to-Manage-Credentials-in-the-AWS-SDKs).
Alternatively, you can set the following environment variables:
```
AWS_ACCESS_KEY_ID=AKID1234567890
AWS_SECRET_ACCESS_KEY=MY-SECRET-KEY
```
### AWS shared config file (`~/.aws/config`)
The AWS SDK for Go added support the shared config file in release [v1.3.0](https://github.com/aws/aws-sdk-go/releases/tag/v1.3.0). You can opt into enabling support for the shared config by setting the environment variable `AWS_SDK_LOAD_CONFIG` to a truthy value. See the [Session](https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/sessions.html) docs for more information about this feature.
## Using the Go SDK
To use a service in the SDK, create a service variable by calling the `New()`
function. Once you have a service client, you can call API operations which each
return response data and a possible error.
To list a set of instance IDs from EC2, you could run:
```go
package main
import (
"fmt"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ec2"
)
func main() {
sess, err := session.NewSession()
if err != nil {
panic(err)
}
// Create an EC2 service object in the "us-west-2" region
// Note that you can also configure your region globally by
// exporting the AWS_REGION environment variable
svc := ec2.New(sess, &aws.Config{Region: aws.String("us-west-2")})
// Call the DescribeInstances Operation
resp, err := svc.DescribeInstances(nil)
if err != nil {
panic(err)
}
// resp has all of the response data, pull out instance IDs:
fmt.Println("> Number of reservation sets: ", len(resp.Reservations))
for idx, res := range resp.Reservations {
fmt.Println(" > Number of instances: ", len(res.Instances))
for _, inst := range resp.Reservations[idx].Instances {
fmt.Println(" - Instance ID: ", *inst.InstanceId)
}
}
}
```
You can find more information and operations in our
[API documentation](http://docs.aws.amazon.com/sdk-for-go/api/).
## License
This SDK is distributed under the
[Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0),
see LICENSE.txt and NOTICE.txt for more information.

145
vendor/github.com/aws/aws-sdk-go/aws/awserr/error.go generated vendored Normal file
View File

@@ -0,0 +1,145 @@
// Package awserr represents API error interface accessors for the SDK.
package awserr
// An Error wraps lower level errors with code, message and an original error.
// The underlying concrete error type may also satisfy other interfaces which
// can be to used to obtain more specific information about the error.
//
// Calling Error() or String() will always include the full information about
// an error based on its underlying type.
//
// Example:
//
// output, err := s3manage.Upload(svc, input, opts)
// if err != nil {
// if awsErr, ok := err.(awserr.Error); ok {
// // Get error details
// log.Println("Error:", awsErr.Code(), awsErr.Message())
//
// // Prints out full error message, including original error if there was one.
// log.Println("Error:", awsErr.Error())
//
// // Get original error
// if origErr := awsErr.OrigErr(); origErr != nil {
// // operate on original error.
// }
// } else {
// fmt.Println(err.Error())
// }
// }
//
type Error interface {
// Satisfy the generic error interface.
error
// Returns the short phrase depicting the classification of the error.
Code() string
// Returns the error details message.
Message() string
// Returns the original error if one was set. Nil is returned if not set.
OrigErr() error
}
// BatchError is a batch of errors which also wraps lower level errors with
// code, message, and original errors. Calling Error() will include all errors
// that occurred in the batch.
//
// Deprecated: Replaced with BatchedErrors. Only defined for backwards
// compatibility.
type BatchError interface {
// Satisfy the generic error interface.
error
// Returns the short phrase depicting the classification of the error.
Code() string
// Returns the error details message.
Message() string
// Returns the original error if one was set. Nil is returned if not set.
OrigErrs() []error
}
// BatchedErrors is a batch of errors which also wraps lower level errors with
// code, message, and original errors. Calling Error() will include all errors
// that occurred in the batch.
//
// Replaces BatchError
type BatchedErrors interface {
// Satisfy the base Error interface.
Error
// Returns the original error if one was set. Nil is returned if not set.
OrigErrs() []error
}
// New returns an Error object described by the code, message, and origErr.
//
// If origErr satisfies the Error interface it will not be wrapped within a new
// Error object and will instead be returned.
func New(code, message string, origErr error) Error {
var errs []error
if origErr != nil {
errs = append(errs, origErr)
}
return newBaseError(code, message, errs)
}
// NewBatchError returns an BatchedErrors with a collection of errors as an
// array of errors.
func NewBatchError(code, message string, errs []error) BatchedErrors {
return newBaseError(code, message, errs)
}
// A RequestFailure is an interface to extract request failure information from
// an Error such as the request ID of the failed request returned by a service.
// RequestFailures may not always have a requestID value if the request failed
// prior to reaching the service such as a connection error.
//
// Example:
//
// output, err := s3manage.Upload(svc, input, opts)
// if err != nil {
// if reqerr, ok := err.(RequestFailure); ok {
// log.Println("Request failed", reqerr.Code(), reqerr.Message(), reqerr.RequestID())
// } else {
// log.Println("Error:", err.Error())
// }
// }
//
// Combined with awserr.Error:
//
// output, err := s3manage.Upload(svc, input, opts)
// if err != nil {
// if awsErr, ok := err.(awserr.Error); ok {
// // Generic AWS Error with Code, Message, and original error (if any)
// fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr())
//
// if reqErr, ok := err.(awserr.RequestFailure); ok {
// // A service error occurred
// fmt.Println(reqErr.StatusCode(), reqErr.RequestID())
// }
// } else {
// fmt.Println(err.Error())
// }
// }
//
type RequestFailure interface {
Error
// The status code of the HTTP response.
StatusCode() int
// The request ID returned by the service for a request failure. This will
// be empty if no request ID is available such as the request failed due
// to a connection error.
RequestID() string
}
// NewRequestFailure returns a new request error wrapper for the given Error
// provided.
func NewRequestFailure(err Error, statusCode int, reqID string) RequestFailure {
return newRequestError(err, statusCode, reqID)
}

194
vendor/github.com/aws/aws-sdk-go/aws/awserr/types.go generated vendored Normal file
View File

@@ -0,0 +1,194 @@
package awserr
import "fmt"
// SprintError returns a string of the formatted error code.
//
// Both extra and origErr are optional. If they are included their lines
// will be added, but if they are not included their lines will be ignored.
func SprintError(code, message, extra string, origErr error) string {
msg := fmt.Sprintf("%s: %s", code, message)
if extra != "" {
msg = fmt.Sprintf("%s\n\t%s", msg, extra)
}
if origErr != nil {
msg = fmt.Sprintf("%s\ncaused by: %s", msg, origErr.Error())
}
return msg
}
// A baseError wraps the code and message which defines an error. It also
// can be used to wrap an original error object.
//
// Should be used as the root for errors satisfying the awserr.Error. Also
// for any error which does not fit into a specific error wrapper type.
type baseError struct {
// Classification of error
code string
// Detailed information about error
message string
// Optional original error this error is based off of. Allows building
// chained errors.
errs []error
}
// newBaseError returns an error object for the code, message, and errors.
//
// code is a short no whitespace phrase depicting the classification of
// the error that is being created.
//
// message is the free flow string containing detailed information about the
// error.
//
// origErrs is the error objects which will be nested under the new errors to
// be returned.
func newBaseError(code, message string, origErrs []error) *baseError {
b := &baseError{
code: code,
message: message,
errs: origErrs,
}
return b
}
// Error returns the string representation of the error.
//
// See ErrorWithExtra for formatting.
//
// Satisfies the error interface.
func (b baseError) Error() string {
size := len(b.errs)
if size > 0 {
return SprintError(b.code, b.message, "", errorList(b.errs))
}
return SprintError(b.code, b.message, "", nil)
}
// String returns the string representation of the error.
// Alias for Error to satisfy the stringer interface.
func (b baseError) String() string {
return b.Error()
}
// Code returns the short phrase depicting the classification of the error.
func (b baseError) Code() string {
return b.code
}
// Message returns the error details message.
func (b baseError) Message() string {
return b.message
}
// OrigErr returns the original error if one was set. Nil is returned if no
// error was set. This only returns the first element in the list. If the full
// list is needed, use BatchedErrors.
func (b baseError) OrigErr() error {
switch len(b.errs) {
case 0:
return nil
case 1:
return b.errs[0]
default:
if err, ok := b.errs[0].(Error); ok {
return NewBatchError(err.Code(), err.Message(), b.errs[1:])
}
return NewBatchError("BatchedErrors",
"multiple errors occurred", b.errs)
}
}
// OrigErrs returns the original errors if one was set. An empty slice is
// returned if no error was set.
func (b baseError) OrigErrs() []error {
return b.errs
}
// So that the Error interface type can be included as an anonymous field
// in the requestError struct and not conflict with the error.Error() method.
type awsError Error
// A requestError wraps a request or service error.
//
// Composed of baseError for code, message, and original error.
type requestError struct {
awsError
statusCode int
requestID string
}
// newRequestError returns a wrapped error with additional information for
// request status code, and service requestID.
//
// Should be used to wrap all request which involve service requests. Even if
// the request failed without a service response, but had an HTTP status code
// that may be meaningful.
//
// Also wraps original errors via the baseError.
func newRequestError(err Error, statusCode int, requestID string) *requestError {
return &requestError{
awsError: err,
statusCode: statusCode,
requestID: requestID,
}
}
// Error returns the string representation of the error.
// Satisfies the error interface.
func (r requestError) Error() string {
extra := fmt.Sprintf("status code: %d, request id: %s",
r.statusCode, r.requestID)
return SprintError(r.Code(), r.Message(), extra, r.OrigErr())
}
// String returns the string representation of the error.
// Alias for Error to satisfy the stringer interface.
func (r requestError) String() string {
return r.Error()
}
// StatusCode returns the wrapped status code for the error
func (r requestError) StatusCode() int {
return r.statusCode
}
// RequestID returns the wrapped requestID
func (r requestError) RequestID() string {
return r.requestID
}
// OrigErrs returns the original errors if one was set. An empty slice is
// returned if no error was set.
func (r requestError) OrigErrs() []error {
if b, ok := r.awsError.(BatchedErrors); ok {
return b.OrigErrs()
}
return []error{r.OrigErr()}
}
// An error list that satisfies the golang interface
type errorList []error
// Error returns the string representation of the error.
//
// Satisfies the error interface.
func (e errorList) Error() string {
msg := ""
// How do we want to handle the array size being zero
if size := len(e); size > 0 {
for i := 0; i < size; i++ {
msg += fmt.Sprintf("%s", e[i].Error())
// We check the next index to see if it is within the slice.
// If it is, then we append a newline. We do this, because unit tests
// could be broken with the additional '\n'
if i+1 < size {
msg += "\n"
}
}
}
return msg
}

108
vendor/github.com/aws/aws-sdk-go/aws/awsutil/copy.go generated vendored Normal file
View File

@@ -0,0 +1,108 @@
package awsutil
import (
"io"
"reflect"
"time"
)
// Copy deeply copies a src structure to dst. Useful for copying request and
// response structures.
//
// Can copy between structs of different type, but will only copy fields which
// are assignable, and exist in both structs. Fields which are not assignable,
// or do not exist in both structs are ignored.
func Copy(dst, src interface{}) {
dstval := reflect.ValueOf(dst)
if !dstval.IsValid() {
panic("Copy dst cannot be nil")
}
rcopy(dstval, reflect.ValueOf(src), true)
}
// CopyOf returns a copy of src while also allocating the memory for dst.
// src must be a pointer type or this operation will fail.
func CopyOf(src interface{}) (dst interface{}) {
dsti := reflect.New(reflect.TypeOf(src).Elem())
dst = dsti.Interface()
rcopy(dsti, reflect.ValueOf(src), true)
return
}
// rcopy performs a recursive copy of values from the source to destination.
//
// root is used to skip certain aspects of the copy which are not valid
// for the root node of a object.
func rcopy(dst, src reflect.Value, root bool) {
if !src.IsValid() {
return
}
switch src.Kind() {
case reflect.Ptr:
if _, ok := src.Interface().(io.Reader); ok {
if dst.Kind() == reflect.Ptr && dst.Elem().CanSet() {
dst.Elem().Set(src)
} else if dst.CanSet() {
dst.Set(src)
}
} else {
e := src.Type().Elem()
if dst.CanSet() && !src.IsNil() {
if _, ok := src.Interface().(*time.Time); !ok {
dst.Set(reflect.New(e))
} else {
tempValue := reflect.New(e)
tempValue.Elem().Set(src.Elem())
// Sets time.Time's unexported values
dst.Set(tempValue)
}
}
if src.Elem().IsValid() {
// Keep the current root state since the depth hasn't changed
rcopy(dst.Elem(), src.Elem(), root)
}
}
case reflect.Struct:
t := dst.Type()
for i := 0; i < t.NumField(); i++ {
name := t.Field(i).Name
srcVal := src.FieldByName(name)
dstVal := dst.FieldByName(name)
if srcVal.IsValid() && dstVal.CanSet() {
rcopy(dstVal, srcVal, false)
}
}
case reflect.Slice:
if src.IsNil() {
break
}
s := reflect.MakeSlice(src.Type(), src.Len(), src.Cap())
dst.Set(s)
for i := 0; i < src.Len(); i++ {
rcopy(dst.Index(i), src.Index(i), false)
}
case reflect.Map:
if src.IsNil() {
break
}
s := reflect.MakeMap(src.Type())
dst.Set(s)
for _, k := range src.MapKeys() {
v := src.MapIndex(k)
v2 := reflect.New(v.Type()).Elem()
rcopy(v2, v, false)
dst.SetMapIndex(k, v2)
}
default:
// Assign the value if possible. If its not assignable, the value would
// need to be converted and the impact of that may be unexpected, or is
// not compatible with the dst type.
if src.Type().AssignableTo(dst.Type()) {
dst.Set(src)
}
}
}

View File

@@ -0,0 +1,265 @@
package awsutil_test
import (
"bytes"
"fmt"
"io"
"io/ioutil"
"testing"
"time"
"github.com/aws/aws-sdk-go/aws/awsutil"
"github.com/stretchr/testify/assert"
)
func ExampleCopy() {
type Foo struct {
A int
B []*string
}
// Create the initial value
str1 := "hello"
str2 := "bye bye"
f1 := &Foo{A: 1, B: []*string{&str1, &str2}}
// Do the copy
var f2 Foo
awsutil.Copy(&f2, f1)
// Print the result
fmt.Println(awsutil.Prettify(f2))
// Output:
// {
// A: 1,
// B: ["hello","bye bye"]
// }
}
func TestCopy1(t *testing.T) {
type Bar struct {
a *int
B *int
c int
D int
}
type Foo struct {
A int
B []*string
C map[string]*int
D *time.Time
E *Bar
}
// Create the initial value
str1 := "hello"
str2 := "bye bye"
int1 := 1
int2 := 2
intPtr1 := 1
intPtr2 := 2
now := time.Now()
f1 := &Foo{
A: 1,
B: []*string{&str1, &str2},
C: map[string]*int{
"A": &int1,
"B": &int2,
},
D: &now,
E: &Bar{
&intPtr1,
&intPtr2,
2,
3,
},
}
// Do the copy
var f2 Foo
awsutil.Copy(&f2, f1)
// Values are equal
assert.Equal(t, f2.A, f1.A)
assert.Equal(t, f2.B, f1.B)
assert.Equal(t, f2.C, f1.C)
assert.Equal(t, f2.D, f1.D)
assert.Equal(t, f2.E.B, f1.E.B)
assert.Equal(t, f2.E.D, f1.E.D)
// But pointers are not!
str3 := "nothello"
int3 := 57
f2.A = 100
*f2.B[0] = str3
*f2.C["B"] = int3
*f2.D = time.Now()
f2.E.a = &int3
*f2.E.B = int3
f2.E.c = 5
f2.E.D = 5
assert.NotEqual(t, f2.A, f1.A)
assert.NotEqual(t, f2.B, f1.B)
assert.NotEqual(t, f2.C, f1.C)
assert.NotEqual(t, f2.D, f1.D)
assert.NotEqual(t, f2.E.a, f1.E.a)
assert.NotEqual(t, f2.E.B, f1.E.B)
assert.NotEqual(t, f2.E.c, f1.E.c)
assert.NotEqual(t, f2.E.D, f1.E.D)
}
func TestCopyNestedWithUnexported(t *testing.T) {
type Bar struct {
a int
B int
}
type Foo struct {
A string
B Bar
}
f1 := &Foo{A: "string", B: Bar{a: 1, B: 2}}
var f2 Foo
awsutil.Copy(&f2, f1)
// Values match
assert.Equal(t, f2.A, f1.A)
assert.NotEqual(t, f2.B, f1.B)
assert.NotEqual(t, f2.B.a, f1.B.a)
assert.Equal(t, f2.B.B, f2.B.B)
}
func TestCopyIgnoreNilMembers(t *testing.T) {
type Foo struct {
A *string
B []string
C map[string]string
}
f := &Foo{}
assert.Nil(t, f.A)
assert.Nil(t, f.B)
assert.Nil(t, f.C)
var f2 Foo
awsutil.Copy(&f2, f)
assert.Nil(t, f2.A)
assert.Nil(t, f2.B)
assert.Nil(t, f2.C)
fcopy := awsutil.CopyOf(f)
f3 := fcopy.(*Foo)
assert.Nil(t, f3.A)
assert.Nil(t, f3.B)
assert.Nil(t, f3.C)
}
func TestCopyPrimitive(t *testing.T) {
str := "hello"
var s string
awsutil.Copy(&s, &str)
assert.Equal(t, "hello", s)
}
func TestCopyNil(t *testing.T) {
var s string
awsutil.Copy(&s, nil)
assert.Equal(t, "", s)
}
func TestCopyReader(t *testing.T) {
var buf io.Reader = bytes.NewReader([]byte("hello world"))
var r io.Reader
awsutil.Copy(&r, buf)
b, err := ioutil.ReadAll(r)
assert.NoError(t, err)
assert.Equal(t, []byte("hello world"), b)
// empty bytes because this is not a deep copy
b, err = ioutil.ReadAll(buf)
assert.NoError(t, err)
assert.Equal(t, []byte(""), b)
}
func TestCopyDifferentStructs(t *testing.T) {
type SrcFoo struct {
A int
B []*string
C map[string]*int
SrcUnique string
SameNameDiffType int
unexportedPtr *int
ExportedPtr *int
}
type DstFoo struct {
A int
B []*string
C map[string]*int
DstUnique int
SameNameDiffType string
unexportedPtr *int
ExportedPtr *int
}
// Create the initial value
str1 := "hello"
str2 := "bye bye"
int1 := 1
int2 := 2
f1 := &SrcFoo{
A: 1,
B: []*string{&str1, &str2},
C: map[string]*int{
"A": &int1,
"B": &int2,
},
SrcUnique: "unique",
SameNameDiffType: 1,
unexportedPtr: &int1,
ExportedPtr: &int2,
}
// Do the copy
var f2 DstFoo
awsutil.Copy(&f2, f1)
// Values are equal
assert.Equal(t, f2.A, f1.A)
assert.Equal(t, f2.B, f1.B)
assert.Equal(t, f2.C, f1.C)
assert.Equal(t, "unique", f1.SrcUnique)
assert.Equal(t, 1, f1.SameNameDiffType)
assert.Equal(t, 0, f2.DstUnique)
assert.Equal(t, "", f2.SameNameDiffType)
assert.Equal(t, int1, *f1.unexportedPtr)
assert.Nil(t, f2.unexportedPtr)
assert.Equal(t, int2, *f1.ExportedPtr)
assert.Equal(t, int2, *f2.ExportedPtr)
}
func ExampleCopyOf() {
type Foo struct {
A int
B []*string
}
// Create the initial value
str1 := "hello"
str2 := "bye bye"
f1 := &Foo{A: 1, B: []*string{&str1, &str2}}
// Do the copy
v := awsutil.CopyOf(f1)
var f2 *Foo = v.(*Foo)
// Print the result
fmt.Println(awsutil.Prettify(f2))
// Output:
// {
// A: 1,
// B: ["hello","bye bye"]
// }
}

27
vendor/github.com/aws/aws-sdk-go/aws/awsutil/equal.go generated vendored Normal file
View File

@@ -0,0 +1,27 @@
package awsutil
import (
"reflect"
)
// DeepEqual returns if the two values are deeply equal like reflect.DeepEqual.
// In addition to this, this method will also dereference the input values if
// possible so the DeepEqual performed will not fail if one parameter is a
// pointer and the other is not.
//
// DeepEqual will not perform indirection of nested values of the input parameters.
func DeepEqual(a, b interface{}) bool {
ra := reflect.Indirect(reflect.ValueOf(a))
rb := reflect.Indirect(reflect.ValueOf(b))
if raValid, rbValid := ra.IsValid(), rb.IsValid(); !raValid && !rbValid {
// If the elements are both nil, and of the same type the are equal
// If they are of different types they are not equal
return reflect.TypeOf(a) == reflect.TypeOf(b)
} else if raValid != rbValid {
// Both values must be valid to be equal
return false
}
return reflect.DeepEqual(ra.Interface(), rb.Interface())
}

View File

@@ -0,0 +1,29 @@
package awsutil_test
import (
"testing"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awsutil"
"github.com/stretchr/testify/assert"
)
func TestDeepEqual(t *testing.T) {
cases := []struct {
a, b interface{}
equal bool
}{
{"a", "a", true},
{"a", "b", false},
{"a", aws.String(""), false},
{"a", nil, false},
{"a", aws.String("a"), true},
{(*bool)(nil), (*bool)(nil), true},
{(*bool)(nil), (*string)(nil), false},
{nil, nil, true},
}
for i, c := range cases {
assert.Equal(t, c.equal, awsutil.DeepEqual(c.a, c.b), "%d, a:%v b:%v, %t", i, c.a, c.b, c.equal)
}
}

View File

@@ -0,0 +1,222 @@
package awsutil
import (
"reflect"
"regexp"
"strconv"
"strings"
"github.com/jmespath/go-jmespath"
)
var indexRe = regexp.MustCompile(`(.+)\[(-?\d+)?\]$`)
// rValuesAtPath returns a slice of values found in value v. The values
// in v are explored recursively so all nested values are collected.
func rValuesAtPath(v interface{}, path string, createPath, caseSensitive, nilTerm bool) []reflect.Value {
pathparts := strings.Split(path, "||")
if len(pathparts) > 1 {
for _, pathpart := range pathparts {
vals := rValuesAtPath(v, pathpart, createPath, caseSensitive, nilTerm)
if len(vals) > 0 {
return vals
}
}
return nil
}
values := []reflect.Value{reflect.Indirect(reflect.ValueOf(v))}
components := strings.Split(path, ".")
for len(values) > 0 && len(components) > 0 {
var index *int64
var indexStar bool
c := strings.TrimSpace(components[0])
if c == "" { // no actual component, illegal syntax
return nil
} else if caseSensitive && c != "*" && strings.ToLower(c[0:1]) == c[0:1] {
// TODO normalize case for user
return nil // don't support unexported fields
}
// parse this component
if m := indexRe.FindStringSubmatch(c); m != nil {
c = m[1]
if m[2] == "" {
index = nil
indexStar = true
} else {
i, _ := strconv.ParseInt(m[2], 10, 32)
index = &i
indexStar = false
}
}
nextvals := []reflect.Value{}
for _, value := range values {
// pull component name out of struct member
if value.Kind() != reflect.Struct {
continue
}
if c == "*" { // pull all members
for i := 0; i < value.NumField(); i++ {
if f := reflect.Indirect(value.Field(i)); f.IsValid() {
nextvals = append(nextvals, f)
}
}
continue
}
value = value.FieldByNameFunc(func(name string) bool {
if c == name {
return true
} else if !caseSensitive && strings.ToLower(name) == strings.ToLower(c) {
return true
}
return false
})
if nilTerm && value.Kind() == reflect.Ptr && len(components[1:]) == 0 {
if !value.IsNil() {
value.Set(reflect.Zero(value.Type()))
}
return []reflect.Value{value}
}
if createPath && value.Kind() == reflect.Ptr && value.IsNil() {
// TODO if the value is the terminus it should not be created
// if the value to be set to its position is nil.
value.Set(reflect.New(value.Type().Elem()))
value = value.Elem()
} else {
value = reflect.Indirect(value)
}
if value.Kind() == reflect.Slice || value.Kind() == reflect.Map {
if !createPath && value.IsNil() {
value = reflect.ValueOf(nil)
}
}
if value.IsValid() {
nextvals = append(nextvals, value)
}
}
values = nextvals
if indexStar || index != nil {
nextvals = []reflect.Value{}
for _, valItem := range values {
value := reflect.Indirect(valItem)
if value.Kind() != reflect.Slice {
continue
}
if indexStar { // grab all indices
for i := 0; i < value.Len(); i++ {
idx := reflect.Indirect(value.Index(i))
if idx.IsValid() {
nextvals = append(nextvals, idx)
}
}
continue
}
// pull out index
i := int(*index)
if i >= value.Len() { // check out of bounds
if createPath {
// TODO resize slice
} else {
continue
}
} else if i < 0 { // support negative indexing
i = value.Len() + i
}
value = reflect.Indirect(value.Index(i))
if value.Kind() == reflect.Slice || value.Kind() == reflect.Map {
if !createPath && value.IsNil() {
value = reflect.ValueOf(nil)
}
}
if value.IsValid() {
nextvals = append(nextvals, value)
}
}
values = nextvals
}
components = components[1:]
}
return values
}
// ValuesAtPath returns a list of values at the case insensitive lexical
// path inside of a structure.
func ValuesAtPath(i interface{}, path string) ([]interface{}, error) {
result, err := jmespath.Search(path, i)
if err != nil {
return nil, err
}
v := reflect.ValueOf(result)
if !v.IsValid() || (v.Kind() == reflect.Ptr && v.IsNil()) {
return nil, nil
}
if s, ok := result.([]interface{}); ok {
return s, err
}
if v.Kind() == reflect.Map && v.Len() == 0 {
return nil, nil
}
if v.Kind() == reflect.Slice {
out := make([]interface{}, v.Len())
for i := 0; i < v.Len(); i++ {
out[i] = v.Index(i).Interface()
}
return out, nil
}
return []interface{}{result}, nil
}
// SetValueAtPath sets a value at the case insensitive lexical path inside
// of a structure.
func SetValueAtPath(i interface{}, path string, v interface{}) {
if rvals := rValuesAtPath(i, path, true, false, v == nil); rvals != nil {
for _, rval := range rvals {
if rval.Kind() == reflect.Ptr && rval.IsNil() {
continue
}
setValue(rval, v)
}
}
}
func setValue(dstVal reflect.Value, src interface{}) {
if dstVal.Kind() == reflect.Ptr {
dstVal = reflect.Indirect(dstVal)
}
srcVal := reflect.ValueOf(src)
if !srcVal.IsValid() { // src is literal nil
if dstVal.CanAddr() {
// Convert to pointer so that pointer's value can be nil'ed
// dstVal = dstVal.Addr()
}
dstVal.Set(reflect.Zero(dstVal.Type()))
} else if srcVal.Kind() == reflect.Ptr {
if srcVal.IsNil() {
srcVal = reflect.Zero(dstVal.Type())
} else {
srcVal = reflect.ValueOf(src).Elem()
}
dstVal.Set(srcVal)
} else {
dstVal.Set(srcVal)
}
}

View File

@@ -0,0 +1,142 @@
package awsutil_test
import (
"testing"
"github.com/aws/aws-sdk-go/aws/awsutil"
"github.com/stretchr/testify/assert"
)
type Struct struct {
A []Struct
z []Struct
B *Struct
D *Struct
C string
E map[string]string
}
var data = Struct{
A: []Struct{{C: "value1"}, {C: "value2"}, {C: "value3"}},
z: []Struct{{C: "value1"}, {C: "value2"}, {C: "value3"}},
B: &Struct{B: &Struct{C: "terminal"}, D: &Struct{C: "terminal2"}},
C: "initial",
}
var data2 = Struct{A: []Struct{
{A: []Struct{{C: "1"}, {C: "1"}, {C: "1"}, {C: "1"}, {C: "1"}}},
{A: []Struct{{C: "2"}, {C: "2"}, {C: "2"}, {C: "2"}, {C: "2"}}},
}}
func TestValueAtPathSuccess(t *testing.T) {
var testCases = []struct {
expect []interface{}
data interface{}
path string
}{
{[]interface{}{"initial"}, data, "C"},
{[]interface{}{"value1"}, data, "A[0].C"},
{[]interface{}{"value2"}, data, "A[1].C"},
{[]interface{}{"value3"}, data, "A[2].C"},
{[]interface{}{"value3"}, data, "a[2].c"},
{[]interface{}{"value3"}, data, "A[-1].C"},
{[]interface{}{"value1", "value2", "value3"}, data, "A[].C"},
{[]interface{}{"terminal"}, data, "B . B . C"},
{[]interface{}{"initial"}, data, "A.D.X || C"},
{[]interface{}{"initial"}, data, "A[0].B || C"},
{[]interface{}{
Struct{A: []Struct{{C: "1"}, {C: "1"}, {C: "1"}, {C: "1"}, {C: "1"}}},
Struct{A: []Struct{{C: "2"}, {C: "2"}, {C: "2"}, {C: "2"}, {C: "2"}}},
}, data2, "A"},
}
for i, c := range testCases {
v, err := awsutil.ValuesAtPath(c.data, c.path)
assert.NoError(t, err, "case %d, expected no error, %s", i, c.path)
assert.Equal(t, c.expect, v, "case %d, %s", i, c.path)
}
}
func TestValueAtPathFailure(t *testing.T) {
var testCases = []struct {
expect []interface{}
errContains string
data interface{}
path string
}{
{nil, "", data, "C.x"},
{nil, "SyntaxError: Invalid token: tDot", data, ".x"},
{nil, "", data, "X.Y.Z"},
{nil, "", data, "A[100].C"},
{nil, "", data, "A[3].C"},
{nil, "", data, "B.B.C.Z"},
{nil, "", data, "z[-1].C"},
{nil, "", nil, "A.B.C"},
{[]interface{}{}, "", Struct{}, "A"},
{nil, "", data, "A[0].B.C"},
{nil, "", data, "D"},
}
for i, c := range testCases {
v, err := awsutil.ValuesAtPath(c.data, c.path)
if c.errContains != "" {
assert.Contains(t, err.Error(), c.errContains, "case %d, expected error, %s", i, c.path)
continue
} else {
assert.NoError(t, err, "case %d, expected no error, %s", i, c.path)
}
assert.Equal(t, c.expect, v, "case %d, %s", i, c.path)
}
}
func TestSetValueAtPathSuccess(t *testing.T) {
var s Struct
awsutil.SetValueAtPath(&s, "C", "test1")
awsutil.SetValueAtPath(&s, "B.B.C", "test2")
awsutil.SetValueAtPath(&s, "B.D.C", "test3")
assert.Equal(t, "test1", s.C)
assert.Equal(t, "test2", s.B.B.C)
assert.Equal(t, "test3", s.B.D.C)
awsutil.SetValueAtPath(&s, "B.*.C", "test0")
assert.Equal(t, "test0", s.B.B.C)
assert.Equal(t, "test0", s.B.D.C)
var s2 Struct
awsutil.SetValueAtPath(&s2, "b.b.c", "test0")
assert.Equal(t, "test0", s2.B.B.C)
awsutil.SetValueAtPath(&s2, "A", []Struct{{}})
assert.Equal(t, []Struct{{}}, s2.A)
str := "foo"
s3 := Struct{}
awsutil.SetValueAtPath(&s3, "b.b.c", str)
assert.Equal(t, "foo", s3.B.B.C)
s3 = Struct{B: &Struct{B: &Struct{C: str}}}
awsutil.SetValueAtPath(&s3, "b.b.c", nil)
assert.Equal(t, "", s3.B.B.C)
s3 = Struct{}
awsutil.SetValueAtPath(&s3, "b.b.c", nil)
assert.Equal(t, "", s3.B.B.C)
s3 = Struct{}
awsutil.SetValueAtPath(&s3, "b.b.c", &str)
assert.Equal(t, "foo", s3.B.B.C)
var s4 struct{ Name *string }
awsutil.SetValueAtPath(&s4, "Name", str)
assert.Equal(t, str, *s4.Name)
s4 = struct{ Name *string }{}
awsutil.SetValueAtPath(&s4, "Name", nil)
assert.Equal(t, (*string)(nil), s4.Name)
s4 = struct{ Name *string }{Name: &str}
awsutil.SetValueAtPath(&s4, "Name", nil)
assert.Equal(t, (*string)(nil), s4.Name)
s4 = struct{ Name *string }{}
awsutil.SetValueAtPath(&s4, "Name", &str)
assert.Equal(t, str, *s4.Name)
}

View File

@@ -0,0 +1,113 @@
package awsutil
import (
"bytes"
"fmt"
"io"
"reflect"
"strings"
)
// Prettify returns the string representation of a value.
func Prettify(i interface{}) string {
var buf bytes.Buffer
prettify(reflect.ValueOf(i), 0, &buf)
return buf.String()
}
// prettify will recursively walk value v to build a textual
// representation of the value.
func prettify(v reflect.Value, indent int, buf *bytes.Buffer) {
for v.Kind() == reflect.Ptr {
v = v.Elem()
}
switch v.Kind() {
case reflect.Struct:
strtype := v.Type().String()
if strtype == "time.Time" {
fmt.Fprintf(buf, "%s", v.Interface())
break
} else if strings.HasPrefix(strtype, "io.") {
buf.WriteString("<buffer>")
break
}
buf.WriteString("{\n")
names := []string{}
for i := 0; i < v.Type().NumField(); i++ {
name := v.Type().Field(i).Name
f := v.Field(i)
if name[0:1] == strings.ToLower(name[0:1]) {
continue // ignore unexported fields
}
if (f.Kind() == reflect.Ptr || f.Kind() == reflect.Slice || f.Kind() == reflect.Map) && f.IsNil() {
continue // ignore unset fields
}
names = append(names, name)
}
for i, n := range names {
val := v.FieldByName(n)
buf.WriteString(strings.Repeat(" ", indent+2))
buf.WriteString(n + ": ")
prettify(val, indent+2, buf)
if i < len(names)-1 {
buf.WriteString(",\n")
}
}
buf.WriteString("\n" + strings.Repeat(" ", indent) + "}")
case reflect.Slice:
strtype := v.Type().String()
if strtype == "[]uint8" {
fmt.Fprintf(buf, "<binary> len %d", v.Len())
break
}
nl, id, id2 := "", "", ""
if v.Len() > 3 {
nl, id, id2 = "\n", strings.Repeat(" ", indent), strings.Repeat(" ", indent+2)
}
buf.WriteString("[" + nl)
for i := 0; i < v.Len(); i++ {
buf.WriteString(id2)
prettify(v.Index(i), indent+2, buf)
if i < v.Len()-1 {
buf.WriteString("," + nl)
}
}
buf.WriteString(nl + id + "]")
case reflect.Map:
buf.WriteString("{\n")
for i, k := range v.MapKeys() {
buf.WriteString(strings.Repeat(" ", indent+2))
buf.WriteString(k.String() + ": ")
prettify(v.MapIndex(k), indent+2, buf)
if i < v.Len()-1 {
buf.WriteString(",\n")
}
}
buf.WriteString("\n" + strings.Repeat(" ", indent) + "}")
default:
if !v.IsValid() {
fmt.Fprint(buf, "<invalid value>")
return
}
format := "%v"
switch v.Interface().(type) {
case string:
format = "%q"
case io.ReadSeeker, io.Reader:
format = "buffer(%p)"
}
fmt.Fprintf(buf, format, v.Interface())
}
}

View File

@@ -0,0 +1,89 @@
package awsutil
import (
"bytes"
"fmt"
"reflect"
"strings"
)
// StringValue returns the string representation of a value.
func StringValue(i interface{}) string {
var buf bytes.Buffer
stringValue(reflect.ValueOf(i), 0, &buf)
return buf.String()
}
func stringValue(v reflect.Value, indent int, buf *bytes.Buffer) {
for v.Kind() == reflect.Ptr {
v = v.Elem()
}
switch v.Kind() {
case reflect.Struct:
buf.WriteString("{\n")
names := []string{}
for i := 0; i < v.Type().NumField(); i++ {
name := v.Type().Field(i).Name
f := v.Field(i)
if name[0:1] == strings.ToLower(name[0:1]) {
continue // ignore unexported fields
}
if (f.Kind() == reflect.Ptr || f.Kind() == reflect.Slice) && f.IsNil() {
continue // ignore unset fields
}
names = append(names, name)
}
for i, n := range names {
val := v.FieldByName(n)
buf.WriteString(strings.Repeat(" ", indent+2))
buf.WriteString(n + ": ")
stringValue(val, indent+2, buf)
if i < len(names)-1 {
buf.WriteString(",\n")
}
}
buf.WriteString("\n" + strings.Repeat(" ", indent) + "}")
case reflect.Slice:
nl, id, id2 := "", "", ""
if v.Len() > 3 {
nl, id, id2 = "\n", strings.Repeat(" ", indent), strings.Repeat(" ", indent+2)
}
buf.WriteString("[" + nl)
for i := 0; i < v.Len(); i++ {
buf.WriteString(id2)
stringValue(v.Index(i), indent+2, buf)
if i < v.Len()-1 {
buf.WriteString("," + nl)
}
}
buf.WriteString(nl + id + "]")
case reflect.Map:
buf.WriteString("{\n")
for i, k := range v.MapKeys() {
buf.WriteString(strings.Repeat(" ", indent+2))
buf.WriteString(k.String() + ": ")
stringValue(v.MapIndex(k), indent+2, buf)
if i < v.Len()-1 {
buf.WriteString(",\n")
}
}
buf.WriteString("\n" + strings.Repeat(" ", indent) + "}")
default:
format := "%v"
switch v.Interface().(type) {
case string:
format = "%q"
}
fmt.Fprintf(buf, format, v.Interface())
}
}

146
vendor/github.com/aws/aws-sdk-go/aws/client/client.go generated vendored Normal file
View File

@@ -0,0 +1,146 @@
package client
import (
"fmt"
"net/http/httputil"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/client/metadata"
"github.com/aws/aws-sdk-go/aws/request"
)
// A Config provides configuration to a service client instance.
type Config struct {
Config *aws.Config
Handlers request.Handlers
Endpoint string
SigningRegion string
SigningName string
}
// ConfigProvider provides a generic way for a service client to receive
// the ClientConfig without circular dependencies.
type ConfigProvider interface {
ClientConfig(serviceName string, cfgs ...*aws.Config) Config
}
// ConfigNoResolveEndpointProvider same as ConfigProvider except it will not
// resolve the endpoint automatically. The service client's endpoint must be
// provided via the aws.Config.Endpoint field.
type ConfigNoResolveEndpointProvider interface {
ClientConfigNoResolveEndpoint(cfgs ...*aws.Config) Config
}
// A Client implements the base client request and response handling
// used by all service clients.
type Client struct {
request.Retryer
metadata.ClientInfo
Config aws.Config
Handlers request.Handlers
}
// New will return a pointer to a new initialized service client.
func New(cfg aws.Config, info metadata.ClientInfo, handlers request.Handlers, options ...func(*Client)) *Client {
svc := &Client{
Config: cfg,
ClientInfo: info,
Handlers: handlers,
}
switch retryer, ok := cfg.Retryer.(request.Retryer); {
case ok:
svc.Retryer = retryer
case cfg.Retryer != nil && cfg.Logger != nil:
s := fmt.Sprintf("WARNING: %T does not implement request.Retryer; using DefaultRetryer instead", cfg.Retryer)
cfg.Logger.Log(s)
fallthrough
default:
maxRetries := aws.IntValue(cfg.MaxRetries)
if cfg.MaxRetries == nil || maxRetries == aws.UseServiceDefaultRetries {
maxRetries = 3
}
svc.Retryer = DefaultRetryer{NumMaxRetries: maxRetries}
}
svc.AddDebugHandlers()
for _, option := range options {
option(svc)
}
return svc
}
// NewRequest returns a new Request pointer for the service API
// operation and parameters.
func (c *Client) NewRequest(operation *request.Operation, params interface{}, data interface{}) *request.Request {
return request.New(c.Config, c.ClientInfo, c.Handlers, c.Retryer, operation, params, data)
}
// AddDebugHandlers injects debug logging handlers into the service to log request
// debug information.
func (c *Client) AddDebugHandlers() {
if !c.Config.LogLevel.AtLeast(aws.LogDebug) {
return
}
c.Handlers.Send.PushFront(logRequest)
c.Handlers.Send.PushBack(logResponse)
}
const logReqMsg = `DEBUG: Request %s/%s Details:
---[ REQUEST POST-SIGN ]-----------------------------
%s
-----------------------------------------------------`
const logReqErrMsg = `DEBUG ERROR: Request %s/%s:
---[ REQUEST DUMP ERROR ]-----------------------------
%s
-----------------------------------------------------`
func logRequest(r *request.Request) {
logBody := r.Config.LogLevel.Matches(aws.LogDebugWithHTTPBody)
dumpedBody, err := httputil.DumpRequestOut(r.HTTPRequest, logBody)
if err != nil {
r.Config.Logger.Log(fmt.Sprintf(logReqErrMsg, r.ClientInfo.ServiceName, r.Operation.Name, err))
return
}
if logBody {
// Reset the request body because dumpRequest will re-wrap the r.HTTPRequest's
// Body as a NoOpCloser and will not be reset after read by the HTTP
// client reader.
r.ResetBody()
}
r.Config.Logger.Log(fmt.Sprintf(logReqMsg, r.ClientInfo.ServiceName, r.Operation.Name, string(dumpedBody)))
}
const logRespMsg = `DEBUG: Response %s/%s Details:
---[ RESPONSE ]--------------------------------------
%s
-----------------------------------------------------`
const logRespErrMsg = `DEBUG ERROR: Response %s/%s:
---[ RESPONSE DUMP ERROR ]-----------------------------
%s
-----------------------------------------------------`
func logResponse(r *request.Request) {
var msg = "no response data"
if r.HTTPResponse != nil {
logBody := r.Config.LogLevel.Matches(aws.LogDebugWithHTTPBody)
dumpedBody, err := httputil.DumpResponse(r.HTTPResponse, logBody)
if err != nil {
r.Config.Logger.Log(fmt.Sprintf(logRespErrMsg, r.ClientInfo.ServiceName, r.Operation.Name, err))
return
}
msg = string(dumpedBody)
} else if r.Error != nil {
msg = r.Error.Error()
}
r.Config.Logger.Log(fmt.Sprintf(logRespMsg, r.ClientInfo.ServiceName, r.Operation.Name, msg))
}

View File

@@ -0,0 +1,90 @@
package client
import (
"math/rand"
"sync"
"time"
"github.com/aws/aws-sdk-go/aws/request"
)
// DefaultRetryer implements basic retry logic using exponential backoff for
// most services. If you want to implement custom retry logic, implement the
// request.Retryer interface or create a structure type that composes this
// struct and override the specific methods. For example, to override only
// the MaxRetries method:
//
// type retryer struct {
// service.DefaultRetryer
// }
//
// // This implementation always has 100 max retries
// func (d retryer) MaxRetries() uint { return 100 }
type DefaultRetryer struct {
NumMaxRetries int
}
// MaxRetries returns the number of maximum returns the service will use to make
// an individual API request.
func (d DefaultRetryer) MaxRetries() int {
return d.NumMaxRetries
}
var seededRand = rand.New(&lockedSource{src: rand.NewSource(time.Now().UnixNano())})
// RetryRules returns the delay duration before retrying this request again
func (d DefaultRetryer) RetryRules(r *request.Request) time.Duration {
// Set the upper limit of delay in retrying at ~five minutes
minTime := 30
throttle := d.shouldThrottle(r)
if throttle {
minTime = 500
}
retryCount := r.RetryCount
if retryCount > 13 {
retryCount = 13
} else if throttle && retryCount > 8 {
retryCount = 8
}
delay := (1 << uint(retryCount)) * (seededRand.Intn(minTime) + minTime)
return time.Duration(delay) * time.Millisecond
}
// ShouldRetry returns true if the request should be retried.
func (d DefaultRetryer) ShouldRetry(r *request.Request) bool {
if r.HTTPResponse.StatusCode >= 500 {
return true
}
return r.IsErrorRetryable() || d.shouldThrottle(r)
}
// ShouldThrottle returns true if the request should be throttled.
func (d DefaultRetryer) shouldThrottle(r *request.Request) bool {
if r.HTTPResponse.StatusCode == 502 ||
r.HTTPResponse.StatusCode == 503 ||
r.HTTPResponse.StatusCode == 504 {
return true
}
return r.IsErrorThrottle()
}
// lockedSource is a thread-safe implementation of rand.Source
type lockedSource struct {
lk sync.Mutex
src rand.Source
}
func (r *lockedSource) Int63() (n int64) {
r.lk.Lock()
n = r.src.Int63()
r.lk.Unlock()
return
}
func (r *lockedSource) Seed(seed int64) {
r.lk.Lock()
r.src.Seed(seed)
r.lk.Unlock()
}

View File

@@ -0,0 +1,12 @@
package metadata
// ClientInfo wraps immutable data from the client.Client structure.
type ClientInfo struct {
ServiceName string
APIVersion string
Endpoint string
SigningName string
SigningRegion string
JSONVersion string
TargetPrefix string
}

459
vendor/github.com/aws/aws-sdk-go/aws/config.go generated vendored Normal file
View File

@@ -0,0 +1,459 @@
package aws
import (
"net/http"
"time"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/endpoints"
)
// UseServiceDefaultRetries instructs the config to use the service's own
// default number of retries. This will be the default action if
// Config.MaxRetries is nil also.
const UseServiceDefaultRetries = -1
// RequestRetryer is an alias for a type that implements the request.Retryer
// interface.
type RequestRetryer interface{}
// A Config provides service configuration for service clients. By default,
// all clients will use the defaults.DefaultConfig tructure.
//
// // Create Session with MaxRetry configuration to be shared by multiple
// // service clients.
// sess := session.Must(session.NewSession(&aws.Config{
// MaxRetries: aws.Int(3),
// }))
//
// // Create S3 service client with a specific Region.
// svc := s3.New(sess, &aws.Config{
// Region: aws.String("us-west-2"),
// })
type Config struct {
// Enables verbose error printing of all credential chain errors.
// Should be used when wanting to see all errors while attempting to
// retrieve credentials.
CredentialsChainVerboseErrors *bool
// The credentials object to use when signing requests. Defaults to a
// chain of credential providers to search for credentials in environment
// variables, shared credential file, and EC2 Instance Roles.
Credentials *credentials.Credentials
// An optional endpoint URL (hostname only or fully qualified URI)
// that overrides the default generated endpoint for a client. Set this
// to `""` to use the default generated endpoint.
//
// @note You must still provide a `Region` value when specifying an
// endpoint for a client.
Endpoint *string
// The resolver to use for looking up endpoints for AWS service clients
// to use based on region.
EndpointResolver endpoints.Resolver
// The region to send requests to. This parameter is required and must
// be configured globally or on a per-client basis unless otherwise
// noted. A full list of regions is found in the "Regions and Endpoints"
// document.
//
// @see http://docs.aws.amazon.com/general/latest/gr/rande.html
// AWS Regions and Endpoints
Region *string
// Set this to `true` to disable SSL when sending requests. Defaults
// to `false`.
DisableSSL *bool
// The HTTP client to use when sending requests. Defaults to
// `http.DefaultClient`.
HTTPClient *http.Client
// An integer value representing the logging level. The default log level
// is zero (LogOff), which represents no logging. To enable logging set
// to a LogLevel Value.
LogLevel *LogLevelType
// The logger writer interface to write logging messages to. Defaults to
// standard out.
Logger Logger
// The maximum number of times that a request will be retried for failures.
// Defaults to -1, which defers the max retry setting to the service
// specific configuration.
MaxRetries *int
// Retryer guides how HTTP requests should be retried in case of
// recoverable failures.
//
// When nil or the value does not implement the request.Retryer interface,
// the request.DefaultRetryer will be used.
//
// When both Retryer and MaxRetries are non-nil, the former is used and
// the latter ignored.
//
// To set the Retryer field in a type-safe manner and with chaining, use
// the request.WithRetryer helper function:
//
// cfg := request.WithRetryer(aws.NewConfig(), myRetryer)
//
Retryer RequestRetryer
// Disables semantic parameter validation, which validates input for
// missing required fields and/or other semantic request input errors.
DisableParamValidation *bool
// Disables the computation of request and response checksums, e.g.,
// CRC32 checksums in Amazon DynamoDB.
DisableComputeChecksums *bool
// Set this to `true` to force the request to use path-style addressing,
// i.e., `http://s3.amazonaws.com/BUCKET/KEY`. By default, the S3 client
// will use virtual hosted bucket addressing when possible
// (`http://BUCKET.s3.amazonaws.com/KEY`).
//
// @note This configuration option is specific to the Amazon S3 service.
// @see http://docs.aws.amazon.com/AmazonS3/latest/dev/VirtualHosting.html
// Amazon S3: Virtual Hosting of Buckets
S3ForcePathStyle *bool
// Set this to `true` to disable the SDK adding the `Expect: 100-Continue`
// header to PUT requests over 2MB of content. 100-Continue instructs the
// HTTP client not to send the body until the service responds with a
// `continue` status. This is useful to prevent sending the request body
// until after the request is authenticated, and validated.
//
// http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPUT.html
//
// 100-Continue is only enabled for Go 1.6 and above. See `http.Transport`'s
// `ExpectContinueTimeout` for information on adjusting the continue wait
// timeout. https://golang.org/pkg/net/http/#Transport
//
// You should use this flag to disble 100-Continue if you experience issues
// with proxies or third party S3 compatible services.
S3Disable100Continue *bool
// Set this to `true` to enable S3 Accelerate feature. For all operations
// compatible with S3 Accelerate will use the accelerate endpoint for
// requests. Requests not compatible will fall back to normal S3 requests.
//
// The bucket must be enable for accelerate to be used with S3 client with
// accelerate enabled. If the bucket is not enabled for accelerate an error
// will be returned. The bucket name must be DNS compatible to also work
// with accelerate.
S3UseAccelerate *bool
// Set this to `true` to disable the EC2Metadata client from overriding the
// default http.Client's Timeout. This is helpful if you do not want the
// EC2Metadata client to create a new http.Client. This options is only
// meaningful if you're not already using a custom HTTP client with the
// SDK. Enabled by default.
//
// Must be set and provided to the session.NewSession() in order to disable
// the EC2Metadata overriding the timeout for default credentials chain.
//
// Example:
// sess := session.Must(session.NewSession(aws.NewConfig()
// .WithEC2MetadataDiableTimeoutOverride(true)))
//
// svc := s3.New(sess)
//
EC2MetadataDisableTimeoutOverride *bool
// Instructs the endpiont to be generated for a service client to
// be the dual stack endpoint. The dual stack endpoint will support
// both IPv4 and IPv6 addressing.
//
// Setting this for a service which does not support dual stack will fail
// to make requets. It is not recommended to set this value on the session
// as it will apply to all service clients created with the session. Even
// services which don't support dual stack endpoints.
//
// If the Endpoint config value is also provided the UseDualStack flag
// will be ignored.
//
// Only supported with.
//
// sess := session.Must(session.NewSession())
//
// svc := s3.New(sess, &aws.Config{
// UseDualStack: aws.Bool(true),
// })
UseDualStack *bool
// SleepDelay is an override for the func the SDK will call when sleeping
// during the lifecycle of a request. Specifically this will be used for
// request delays. This value should only be used for testing. To adjust
// the delay of a request see the aws/client.DefaultRetryer and
// aws/request.Retryer.
//
// SleepDelay will prevent any Context from being used for canceling retry
// delay of an API operation. It is recommended to not use SleepDelay at all
// and specify a Retryer instead.
SleepDelay func(time.Duration)
// DisableRestProtocolURICleaning will not clean the URL path when making rest protocol requests.
// Will default to false. This would only be used for empty directory names in s3 requests.
//
// Example:
// sess := session.Must(session.NewSession(&aws.Config{
// DisableRestProtocolURICleaning: aws.Bool(true),
// }))
//
// svc := s3.New(sess)
// out, err := svc.GetObject(&s3.GetObjectInput {
// Bucket: aws.String("bucketname"),
// Key: aws.String("//foo//bar//moo"),
// })
DisableRestProtocolURICleaning *bool
}
// NewConfig returns a new Config pointer that can be chained with builder
// methods to set multiple configuration values inline without using pointers.
//
// // Create Session with MaxRetry configuration to be shared by multiple
// // service clients.
// sess := session.Must(session.NewSession(aws.NewConfig().
// WithMaxRetries(3),
// ))
//
// // Create S3 service client with a specific Region.
// svc := s3.New(sess, aws.NewConfig().
// WithRegion("us-west-2"),
// )
func NewConfig() *Config {
return &Config{}
}
// WithCredentialsChainVerboseErrors sets a config verbose errors boolean and returning
// a Config pointer.
func (c *Config) WithCredentialsChainVerboseErrors(verboseErrs bool) *Config {
c.CredentialsChainVerboseErrors = &verboseErrs
return c
}
// WithCredentials sets a config Credentials value returning a Config pointer
// for chaining.
func (c *Config) WithCredentials(creds *credentials.Credentials) *Config {
c.Credentials = creds
return c
}
// WithEndpoint sets a config Endpoint value returning a Config pointer for
// chaining.
func (c *Config) WithEndpoint(endpoint string) *Config {
c.Endpoint = &endpoint
return c
}
// WithEndpointResolver sets a config EndpointResolver value returning a
// Config pointer for chaining.
func (c *Config) WithEndpointResolver(resolver endpoints.Resolver) *Config {
c.EndpointResolver = resolver
return c
}
// WithRegion sets a config Region value returning a Config pointer for
// chaining.
func (c *Config) WithRegion(region string) *Config {
c.Region = &region
return c
}
// WithDisableSSL sets a config DisableSSL value returning a Config pointer
// for chaining.
func (c *Config) WithDisableSSL(disable bool) *Config {
c.DisableSSL = &disable
return c
}
// WithHTTPClient sets a config HTTPClient value returning a Config pointer
// for chaining.
func (c *Config) WithHTTPClient(client *http.Client) *Config {
c.HTTPClient = client
return c
}
// WithMaxRetries sets a config MaxRetries value returning a Config pointer
// for chaining.
func (c *Config) WithMaxRetries(max int) *Config {
c.MaxRetries = &max
return c
}
// WithDisableParamValidation sets a config DisableParamValidation value
// returning a Config pointer for chaining.
func (c *Config) WithDisableParamValidation(disable bool) *Config {
c.DisableParamValidation = &disable
return c
}
// WithDisableComputeChecksums sets a config DisableComputeChecksums value
// returning a Config pointer for chaining.
func (c *Config) WithDisableComputeChecksums(disable bool) *Config {
c.DisableComputeChecksums = &disable
return c
}
// WithLogLevel sets a config LogLevel value returning a Config pointer for
// chaining.
func (c *Config) WithLogLevel(level LogLevelType) *Config {
c.LogLevel = &level
return c
}
// WithLogger sets a config Logger value returning a Config pointer for
// chaining.
func (c *Config) WithLogger(logger Logger) *Config {
c.Logger = logger
return c
}
// WithS3ForcePathStyle sets a config S3ForcePathStyle value returning a Config
// pointer for chaining.
func (c *Config) WithS3ForcePathStyle(force bool) *Config {
c.S3ForcePathStyle = &force
return c
}
// WithS3Disable100Continue sets a config S3Disable100Continue value returning
// a Config pointer for chaining.
func (c *Config) WithS3Disable100Continue(disable bool) *Config {
c.S3Disable100Continue = &disable
return c
}
// WithS3UseAccelerate sets a config S3UseAccelerate value returning a Config
// pointer for chaining.
func (c *Config) WithS3UseAccelerate(enable bool) *Config {
c.S3UseAccelerate = &enable
return c
}
// WithUseDualStack sets a config UseDualStack value returning a Config
// pointer for chaining.
func (c *Config) WithUseDualStack(enable bool) *Config {
c.UseDualStack = &enable
return c
}
// WithEC2MetadataDisableTimeoutOverride sets a config EC2MetadataDisableTimeoutOverride value
// returning a Config pointer for chaining.
func (c *Config) WithEC2MetadataDisableTimeoutOverride(enable bool) *Config {
c.EC2MetadataDisableTimeoutOverride = &enable
return c
}
// WithSleepDelay overrides the function used to sleep while waiting for the
// next retry. Defaults to time.Sleep.
func (c *Config) WithSleepDelay(fn func(time.Duration)) *Config {
c.SleepDelay = fn
return c
}
// MergeIn merges the passed in configs into the existing config object.
func (c *Config) MergeIn(cfgs ...*Config) {
for _, other := range cfgs {
mergeInConfig(c, other)
}
}
func mergeInConfig(dst *Config, other *Config) {
if other == nil {
return
}
if other.CredentialsChainVerboseErrors != nil {
dst.CredentialsChainVerboseErrors = other.CredentialsChainVerboseErrors
}
if other.Credentials != nil {
dst.Credentials = other.Credentials
}
if other.Endpoint != nil {
dst.Endpoint = other.Endpoint
}
if other.EndpointResolver != nil {
dst.EndpointResolver = other.EndpointResolver
}
if other.Region != nil {
dst.Region = other.Region
}
if other.DisableSSL != nil {
dst.DisableSSL = other.DisableSSL
}
if other.HTTPClient != nil {
dst.HTTPClient = other.HTTPClient
}
if other.LogLevel != nil {
dst.LogLevel = other.LogLevel
}
if other.Logger != nil {
dst.Logger = other.Logger
}
if other.MaxRetries != nil {
dst.MaxRetries = other.MaxRetries
}
if other.Retryer != nil {
dst.Retryer = other.Retryer
}
if other.DisableParamValidation != nil {
dst.DisableParamValidation = other.DisableParamValidation
}
if other.DisableComputeChecksums != nil {
dst.DisableComputeChecksums = other.DisableComputeChecksums
}
if other.S3ForcePathStyle != nil {
dst.S3ForcePathStyle = other.S3ForcePathStyle
}
if other.S3Disable100Continue != nil {
dst.S3Disable100Continue = other.S3Disable100Continue
}
if other.S3UseAccelerate != nil {
dst.S3UseAccelerate = other.S3UseAccelerate
}
if other.UseDualStack != nil {
dst.UseDualStack = other.UseDualStack
}
if other.EC2MetadataDisableTimeoutOverride != nil {
dst.EC2MetadataDisableTimeoutOverride = other.EC2MetadataDisableTimeoutOverride
}
if other.SleepDelay != nil {
dst.SleepDelay = other.SleepDelay
}
if other.DisableRestProtocolURICleaning != nil {
dst.DisableRestProtocolURICleaning = other.DisableRestProtocolURICleaning
}
}
// Copy will return a shallow copy of the Config object. If any additional
// configurations are provided they will be merged into the new config returned.
func (c *Config) Copy(cfgs ...*Config) *Config {
dst := &Config{}
dst.MergeIn(c)
for _, cfg := range cfgs {
dst.MergeIn(cfg)
}
return dst
}

86
vendor/github.com/aws/aws-sdk-go/aws/config_test.go generated vendored Normal file
View File

@@ -0,0 +1,86 @@
package aws
import (
"net/http"
"reflect"
"testing"
"github.com/aws/aws-sdk-go/aws/credentials"
)
var testCredentials = credentials.NewStaticCredentials("AKID", "SECRET", "SESSION")
var copyTestConfig = Config{
Credentials: testCredentials,
Endpoint: String("CopyTestEndpoint"),
Region: String("COPY_TEST_AWS_REGION"),
DisableSSL: Bool(true),
HTTPClient: http.DefaultClient,
LogLevel: LogLevel(LogDebug),
Logger: NewDefaultLogger(),
MaxRetries: Int(3),
DisableParamValidation: Bool(true),
DisableComputeChecksums: Bool(true),
S3ForcePathStyle: Bool(true),
}
func TestCopy(t *testing.T) {
want := copyTestConfig
got := copyTestConfig.Copy()
if !reflect.DeepEqual(*got, want) {
t.Errorf("Copy() = %+v", got)
t.Errorf(" want %+v", want)
}
got.Region = String("other")
if got.Region == want.Region {
t.Errorf("Expect setting copy values not not reflect in source")
}
}
func TestCopyReturnsNewInstance(t *testing.T) {
want := copyTestConfig
got := copyTestConfig.Copy()
if got == &want {
t.Errorf("Copy() = %p; want different instance as source %p", got, &want)
}
}
var mergeTestZeroValueConfig = Config{}
var mergeTestConfig = Config{
Credentials: testCredentials,
Endpoint: String("MergeTestEndpoint"),
Region: String("MERGE_TEST_AWS_REGION"),
DisableSSL: Bool(true),
HTTPClient: http.DefaultClient,
LogLevel: LogLevel(LogDebug),
Logger: NewDefaultLogger(),
MaxRetries: Int(10),
DisableParamValidation: Bool(true),
DisableComputeChecksums: Bool(true),
S3ForcePathStyle: Bool(true),
}
var mergeTests = []struct {
cfg *Config
in *Config
want *Config
}{
{&Config{}, nil, &Config{}},
{&Config{}, &mergeTestZeroValueConfig, &Config{}},
{&Config{}, &mergeTestConfig, &mergeTestConfig},
}
func TestMerge(t *testing.T) {
for i, tt := range mergeTests {
got := tt.cfg.Copy()
got.MergeIn(tt.in)
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("Config %d %+v", i, tt.cfg)
t.Errorf(" Merge(%+v)", tt.in)
t.Errorf(" got %+v", got)
t.Errorf(" want %+v", tt.want)
}
}
}

Some files were not shown because too many files have changed in this diff Show More