├── .gitignore ├── LICENSE ├── README.md ├── ast ├── base.go ├── ddl.go ├── element │ ├── basic.go │ └── datatype.go └── node.go ├── go.mod ├── go.sum ├── lexer.go ├── lexer_test.go ├── parser.go ├── parser_test.go ├── sql.go ├── sql.y ├── test ├── alter_table_add_column.sql ├── alter_table_constraint.sql ├── alter_table_drop_column.sql ├── alter_table_modify_column.sql ├── alter_table_rename.sql ├── create_index.sql ├── create_table.sql ├── drop_index.sql ├── drop_table.sql └── test_comments.sql └── vendor ├── github.com ├── davecgh │ └── go-spew │ │ ├── LICENSE │ │ └── spew │ │ ├── bypass.go │ │ ├── bypasssafe.go │ │ ├── common.go │ │ ├── config.go │ │ ├── doc.go │ │ ├── dump.go │ │ ├── format.go │ │ └── spew.go ├── pmezard │ └── go-difflib │ │ ├── LICENSE │ │ └── difflib │ │ └── difflib.go ├── stretchr │ └── testify │ │ ├── LICENSE │ │ └── assert │ │ ├── assertion_compare.go │ │ ├── assertion_format.go │ │ ├── assertion_format.go.tmpl │ │ ├── assertion_forward.go │ │ ├── assertion_forward.go.tmpl │ │ ├── assertion_order.go │ │ ├── assertions.go │ │ ├── doc.go │ │ ├── errors.go │ │ ├── forward_assertions.go │ │ └── http_assertions.go └── timtadh │ ├── data-structures │ ├── LICENSE │ ├── errors │ │ └── errors.go │ ├── hashtable │ │ ├── hashtable.go │ │ └── linhash.go │ ├── linked │ │ ├── linked.go │ │ └── unique.go │ ├── list │ │ ├── array_list.go │ │ └── sorted.go │ ├── rand │ │ └── rand.go │ ├── set │ │ ├── mapset.go │ │ ├── ops.go │ │ ├── setmap.go │ │ └── sortedset.go │ ├── tree │ │ ├── avl │ │ │ ├── avltree.go │ │ │ └── imm_avltree.go │ │ └── util.go │ └── types │ │ ├── int.go │ │ ├── map_entry.go │ │ ├── string.go │ │ ├── types.go │ │ └── util.go │ └── lexmachine │ ├── .activate │ ├── .gitignore │ ├── .gitmodules │ ├── CHANGELOG │ ├── Gopkg.lock │ ├── Gopkg.toml │ ├── LICENSE │ ├── README.md │ ├── dfa │ ├── dfa_helpers.go │ └── gen.go │ ├── doc.go │ ├── frontend │ ├── ast.go │ ├── ast_equality.go │ ├── desugar.go │ ├── gen.go │ └── parser.go │ ├── grammar │ ├── inst │ └── inst.go │ ├── lexer.go │ ├── machines │ ├── dfa_machine.go │ └── machine.go │ └── queue │ └── queue.go ├── gopkg.in └── yaml.v3 │ ├── .travis.yml │ ├── LICENSE │ ├── NOTICE │ ├── README.md │ ├── apic.go │ ├── decode.go │ ├── emitterc.go │ ├── encode.go │ ├── go.mod │ ├── parserc.go │ ├── readerc.go │ ├── resolve.go │ ├── scannerc.go │ ├── sorter.go │ ├── writerc.go │ ├── yaml.go │ ├── yamlh.go │ └── yamlprivateh.go └── modules.txt /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, built with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | 14 | y.output 15 | 16 | .idea/ 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Oracle SQL Parser 2 | this is an oracle sql parser. ref: https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf 3 | 4 | ## supported statement 5 | |statement| sub statement |yacc|ast| 6 | |----|----|----|----| 7 | |Alter table|Add column| :heavy_check_mark:|:heavy_check_mark:| 8 | |Alter table|Modify column| :heavy_check_mark:|:heavy_check_mark:| 9 | |Alter table|Drop column| :heavy_check_mark:|:heavy_check_mark:| 10 | |Alter table|Rename column| :heavy_check_mark:|:heavy_check_mark:| 11 | |Alter table|Add constraint| :heavy_check_mark:| :heavy_check_mark:| 12 | |Alter table|Modify constraint| :heavy_check_mark:| :heavy_check_mark:| 13 | |Alter table|Rename constraint| :heavy_check_mark:| :heavy_check_mark:| 14 | |Alter table|Drop constraint| :heavy_check_mark:| :heavy_check_mark:| 15 | |Create table|Relational table|:heavy_check_mark:|:heavy_check_mark:| 16 | |Create index|Relational table|:heavy_check_mark:| | 17 | |Drop table|-|:heavy_check_mark:|:heavy_check_mark:| 18 | |Drop index|-|:heavy_check_mark:|:heavy_check_mark:| 19 | 20 | ## usage 21 | ```go 22 | package main 23 | 24 | import ( 25 | "fmt" 26 | "github.com/sjjian/oracle-sql-parser" 27 | "github.com/sjjian/oracle-sql-parser/ast" 28 | ) 29 | 30 | func main() { 31 | stmts, err := parser.Parser("alter table db1.t1 add (id number, name varchar2(255))") 32 | if err != nil { 33 | fmt.Println(err) 34 | return 35 | } 36 | stmt := stmts[0] 37 | switch s := stmt.(type) { 38 | case *ast.AlterTableStmt: 39 | fmt.Println(s.TableName.Table.Value) // t1 40 | } 41 | } 42 | ``` 43 | -------------------------------------------------------------------------------- /ast/base.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "github.com/sjjian/oracle-sql-parser/ast/element" 5 | ) 6 | 7 | type TableName struct { 8 | Schema *element.Identifier 9 | Table *element.Identifier 10 | } 11 | 12 | type IndexName struct { 13 | Schema *element.Identifier 14 | Index *element.Identifier 15 | } 16 | 17 | type Collation struct { 18 | Name *element.Identifier 19 | } 20 | 21 | type ColumnProp int 22 | 23 | const ( 24 | ColumnPropEmpty ColumnProp = iota 25 | ColumnPropSort // for add column 26 | ColumnPropInvisible 27 | ColumnPropVisible 28 | ColumnPropSubstitutable // for modify column 29 | ColumnPropNotSubstitutable // for modify column 30 | ColumnPropSubstitutableForce // for modify column 31 | ColumnPropNotSubstitutableForce // for modify column 32 | ) 33 | 34 | type ColumnDefault struct { 35 | OnNull bool 36 | Value interface{} 37 | } 38 | 39 | type ConstraintType int 40 | 41 | const ( 42 | ConstraintTypeDefault ConstraintType = iota 43 | ConstraintTypeNull 44 | ConstraintTypeNotNull 45 | ConstraintTypeUnique 46 | ConstraintTypePK 47 | ConstraintTypeReferences 48 | ) 49 | 50 | //type ConstraintState int 51 | 52 | //const ( 53 | // ConstraintStateDeferrable ConstraintState = iota 54 | // ConstraintStateNotDeferrable 55 | // ConstraintStateInitiallyDeferred 56 | // ConstraintStateInitiallyImmediate 57 | // ConstraintStateRely 58 | // ConstraintStateNorely 59 | //) 60 | 61 | type DropColumnType int 62 | 63 | const ( 64 | DropColumnTypeDrop DropColumnType = iota 65 | DropColumnTypeSetUnused 66 | DropColumnTypeDropUnusedColumns 67 | DropColumnTypeDropColumnsContinue 68 | ) 69 | 70 | type DropColumnProp int 71 | 72 | const ( 73 | DropColumnPropEmpty DropColumnProp = iota 74 | DropColumnPropCascade 75 | DropColumnPropInvalidate 76 | DropColumnPropOnline 77 | ) 78 | -------------------------------------------------------------------------------- /ast/ddl.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | import ( 4 | "github.com/sjjian/oracle-sql-parser/ast/element" 5 | ) 6 | 7 | /* 8 | Alter Table Statement 9 | see: https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ALTER-TABLE.html#GUID-552E7373-BF93-477D-9DA3-B2C9386F2877 10 | */ 11 | 12 | type AlterTableStmt struct { 13 | node 14 | TableName *TableName 15 | AlterTableClauses []AlterTableClause 16 | } 17 | 18 | type AlterTableClause interface { 19 | IsAlterTableClause() 20 | } 21 | 22 | type alterTableClause struct{} 23 | 24 | func (c *alterTableClause) IsAlterTableClause() {} 25 | 26 | type AddColumnClause struct { 27 | alterTableClause 28 | Columns []*ColumnDef 29 | } 30 | 31 | type ModifyColumnClause struct { 32 | alterTableClause 33 | Columns []*ColumnDef 34 | } 35 | 36 | type DropColumnClause struct { 37 | alterTableClause 38 | Type DropColumnType 39 | Columns []*element.Identifier 40 | Props []DropColumnProp 41 | CheckPoint *int 42 | } 43 | 44 | type RenameColumnClause struct { 45 | alterTableClause 46 | OldName *element.Identifier 47 | NewName *element.Identifier 48 | } 49 | 50 | type AddConstraintClause struct { 51 | alterTableClause 52 | Constraints []*OutOfLineConstraint 53 | } 54 | 55 | type ModifyConstraintClause struct { 56 | alterTableClause 57 | Constraint *OutOfLineConstraint 58 | } 59 | 60 | type RenameConstraintClause struct { 61 | alterTableClause 62 | OldName *element.Identifier 63 | NewName *element.Identifier 64 | } 65 | 66 | type DropConstraintClause struct { 67 | alterTableClause 68 | Constraint *OutOfLineConstraint 69 | } 70 | 71 | /* 72 | Create Table Statement 73 | see: https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-TABLE.html#GUID-F9CE0CC3-13AE-4744-A43C-EAC7A71AAAB6 74 | */ 75 | 76 | type CreateTableStmt struct { 77 | node 78 | TableName *TableName 79 | RelTable *RelTableDef 80 | } 81 | 82 | type RelTableDef struct { 83 | TableStructs []TableStructDef 84 | } 85 | 86 | type TableStructDef interface { 87 | IsTableStructDef() 88 | } 89 | 90 | type tableStructDef struct{} 91 | 92 | func (c *tableStructDef) IsTableStructDef() {} 93 | 94 | type ColumnDef struct { 95 | tableStructDef 96 | ColumnName *element.Identifier 97 | Datatype element.Datatype 98 | Collation *Collation 99 | Props []ColumnProp 100 | Default *ColumnDefault 101 | Constraints []*InlineConstraint 102 | } 103 | 104 | type InlineConstraint struct { 105 | Name *element.Identifier 106 | Type ConstraintType 107 | } 108 | 109 | type OutOfLineConstraint struct { 110 | tableStructDef 111 | InlineConstraint 112 | Columns []*element.Identifier 113 | } 114 | 115 | /* 116 | Create Index Statement 117 | see: https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-INDEX.html#GUID-1F89BBC0-825F-4215-AF71-7588E31D8BFE 118 | */ 119 | 120 | type CreateIndexStmt struct { 121 | node 122 | } 123 | 124 | /* 125 | Drop Table Statement 126 | see: https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-INDEX.html#GUID-1F89BBC0-825F-4215-AF71-7588E31D8BFE 127 | */ 128 | type DropTableStmt struct { 129 | node 130 | TableName *TableName 131 | } 132 | 133 | /* 134 | Drop Index Statement 135 | see: https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/DROP-INDEX.html#GUID-F60F75DF-2866-4F93-BB7F-8FCE64BF67B6 136 | */ 137 | type DropIndexStmt struct { 138 | node 139 | IndexName *IndexName 140 | } 141 | -------------------------------------------------------------------------------- /ast/element/basic.go: -------------------------------------------------------------------------------- 1 | package element 2 | 3 | const ( 4 | IdentifierTypeQuoted = iota // "schema" . "table" 5 | IdentifierTypeNonQuoted // schema . table 6 | ) 7 | 8 | type Identifier struct { 9 | Typ int 10 | Value string 11 | } 12 | 13 | type NumberOrAsterisk struct { 14 | Number int 15 | IsAsterisk bool 16 | } -------------------------------------------------------------------------------- /ast/element/datatype.go: -------------------------------------------------------------------------------- 1 | package element 2 | 3 | type Datatype interface { 4 | DataDef() DataDef 5 | } 6 | 7 | type DataDef int 8 | 9 | const ( 10 | DataDefChar DataDef = iota 11 | DataDefVarchar2 12 | DataDefNChar 13 | DataDefNVarChar2 14 | DataDefNumber 15 | DataDefFloat 16 | DataDefBinaryFloat 17 | DataDefBinaryDouble 18 | DataDefLong 19 | DataDefLongRaw 20 | DataDefRaw 21 | DataDefDate 22 | DataDefTimestamp 23 | DataDefIntervalYear 24 | DataDefIntervalDay 25 | DataDefBlob 26 | DataDefClob 27 | DataDefNClob 28 | DataDefBFile 29 | DataDefRowId 30 | DataDefURowId 31 | DataDefCharacter 32 | DataDefCharacterVarying 33 | DataDefCharVarying 34 | DataDefNCharVarying 35 | DataDefVarchar 36 | DataDefNationalCharacter 37 | DataDefNationalCharacterVarying 38 | DataDefNationalChar 39 | DataDefNationalCharVarying 40 | DataDefNumeric 41 | DataDefDecimal 42 | DataDefDec 43 | DataDefInteger 44 | DataDefInt 45 | DataDefSmallInt 46 | DataDefDoublePrecision 47 | DataDefReal 48 | DataDefXMLType 49 | ) 50 | 51 | type datatype struct { 52 | typ DataDef 53 | } 54 | 55 | func (d *datatype) DataDef () DataDef { 56 | return d.typ 57 | } 58 | 59 | func (d *datatype) SetDataDef(typ DataDef) { 60 | d.typ = typ 61 | } 62 | 63 | // Char is "Char" and "Character" 64 | type Char struct { 65 | datatype 66 | Size *int 67 | IsByteSize bool 68 | IsCharSize bool 69 | } 70 | 71 | // Varchar2 include: "Varchar2", "Char Varying", "Character Varying", "Varchar" 72 | type Varchar2 struct { 73 | Char 74 | } 75 | 76 | // NChar include: "Nchar", "National Character", "National Char". 77 | type NChar struct { 78 | datatype 79 | Size *int 80 | } 81 | 82 | // NVarchar2 include: "NVarchar2", "National Character Varying", "National Char Varying", "NChar Varying" 83 | type NVarchar2 struct { 84 | NChar 85 | } 86 | 87 | type Raw struct { 88 | datatype 89 | Size *int 90 | } 91 | 92 | type RowId struct { 93 | datatype 94 | } 95 | 96 | type URowId struct { 97 | datatype 98 | Size *int 99 | } 100 | 101 | type Date struct { 102 | datatype 103 | } 104 | 105 | type Timestamp struct { 106 | datatype 107 | FractionalSecondsPrecision *int 108 | WithTimeZone bool 109 | WithLocalTimeZone bool 110 | } 111 | 112 | type IntervalYear struct { 113 | datatype 114 | Precision *int 115 | } 116 | 117 | type IntervalDay struct { 118 | datatype 119 | Precision *int 120 | FractionalSecondsPrecision *int 121 | } 122 | 123 | // Number include: "Number", "Numeric", "Decimal", "Dec", "Integer", "Int", "Smallint"; 124 | // Integer is a alias of Number(38); 125 | // Int is a alias of Number(38); 126 | // Smallint is a alias of Number(38) 127 | type Number struct { 128 | datatype 129 | Precision *NumberOrAsterisk 130 | Scale *int 131 | } 132 | 133 | // Float is a subtype of Number, include: "Float", "", "DoublePrecision", "Real"; 134 | // DoublePrecision is a alias of FLOAT(126); 135 | // Real is a alias of FLOAT(63). 136 | type Float struct { 137 | datatype 138 | Precision *NumberOrAsterisk 139 | } 140 | 141 | type BinaryFloat struct { 142 | datatype 143 | } 144 | 145 | type BinaryDouble struct { 146 | datatype 147 | } 148 | 149 | type Long struct { 150 | datatype 151 | } 152 | 153 | type LongRaw struct { 154 | datatype 155 | } 156 | 157 | type Blob struct { 158 | datatype 159 | } 160 | 161 | type Clob struct { 162 | datatype 163 | } 164 | 165 | type NClob struct { 166 | datatype 167 | } 168 | 169 | type BFile struct { 170 | datatype 171 | } 172 | 173 | type XMLType struct { 174 | datatype 175 | } -------------------------------------------------------------------------------- /ast/node.go: -------------------------------------------------------------------------------- 1 | package ast 2 | 3 | type Node interface { 4 | Text() string 5 | SetText(text string) 6 | } 7 | 8 | // node is the struct implements Node interface 9 | type node struct { 10 | text string 11 | } 12 | 13 | // Text implements Node interface. 14 | func (n *node) Text() string { 15 | return n.text 16 | } 17 | 18 | // SetText implements Node interface. 19 | func (n *node) SetText(text string) { 20 | n.text = text 21 | } 22 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/sjjian/oracle-sql-parser 2 | 3 | go 1.16 4 | 5 | require ( 6 | github.com/stretchr/testify v1.7.0 7 | github.com/timtadh/data-structures v0.5.3 // indirect 8 | github.com/timtadh/lexmachine v0.2.2 9 | ) 10 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= 2 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 6 | github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= 7 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 8 | github.com/timtadh/data-structures v0.5.3 h1:F2tEjoG9qWIyUjbvXVgJqEOGJPMIiYn7U5W5mE+i/vQ= 9 | github.com/timtadh/data-structures v0.5.3/go.mod h1:9R4XODhJ8JdWFEI8P/HJKqxuJctfBQw6fDibMQny2oU= 10 | github.com/timtadh/lexmachine v0.2.2 h1:g55RnjdYazm5wnKv59pwFcBJHOyvTPfDEoz21s4PHmY= 11 | github.com/timtadh/lexmachine v0.2.2/go.mod h1:GBJvD5OAfRn/gnp92zb9KTgHLB7akKyxmVivoYCcjQI= 12 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= 13 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 14 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= 15 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 16 | -------------------------------------------------------------------------------- /lexer_test.go: -------------------------------------------------------------------------------- 1 | package parser 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | func TestGenKeywordIdent(t *testing.T) { 10 | testCases := map[string][]byte{ 11 | "a": []byte("[Aa]"), 12 | "B": []byte("[Bb]"), 13 | "case": []byte("[Cc][Aa][Ss][Ee]"), 14 | "CASE": []byte("[Cc][Aa][Ss][Ee]"), 15 | "CaSe": []byte("[Cc][Aa][Ss][Ee]"), 16 | "a_b": []byte("[Aa]_[Bb]"), 17 | "": nil, 18 | } 19 | for input, expect := range testCases { 20 | actual := genKeywordIdent(input) 21 | assert.Equal(t, string(expect), string(actual)) 22 | } 23 | } 24 | 25 | type genGroupKeywordCase struct { 26 | expect []byte 27 | input []string 28 | } 29 | 30 | func TestGenGroupKeywordIdent(t *testing.T) { 31 | testCases := []genGroupKeywordCase{ 32 | { 33 | input: []string{}, 34 | expect: nil, 35 | }, 36 | { 37 | input: []string{"a"}, 38 | expect: []byte("[Aa]"), 39 | }, 40 | { 41 | input: []string{"B"}, 42 | expect: []byte("[Bb]"), 43 | }, 44 | { 45 | input: []string{"a", "B"}, 46 | expect: []byte("[Aa]( |\t|\n|\r)+[Bb]"), 47 | }, 48 | { 49 | input: []string{"a", "B", "CasE"}, 50 | expect: []byte("[Aa]( |\t|\n|\r)+[Bb]( |\t|\n|\r)+[Cc][Aa][Ss][Ee]"), 51 | }, 52 | } 53 | for _, c := range testCases { 54 | actual := genGroupKeywordIdent(c.input...) 55 | assert.Equal(t, string(c.expect), string(actual)) 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /parser.go: -------------------------------------------------------------------------------- 1 | package parser 2 | 3 | import ( 4 | "fmt" 5 | "github.com/sjjian/oracle-sql-parser/ast" 6 | ) 7 | 8 | func Parser(query string) ([]ast.Node, error) { 9 | l, err := NewLexer(query) 10 | if err != nil { 11 | fmt.Println(err) 12 | return nil, err 13 | } 14 | 15 | //yyDebug = 4 16 | yyParse(l) 17 | if l.err != nil { 18 | return nil, l.err 19 | } 20 | return l.result, nil 21 | } 22 | -------------------------------------------------------------------------------- /parser_test.go: -------------------------------------------------------------------------------- 1 | package parser 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "path/filepath" 7 | "strings" 8 | "testing" 9 | 10 | "github.com/sjjian/oracle-sql-parser/ast" 11 | "github.com/stretchr/testify/assert" 12 | ) 13 | 14 | func TestParserSQLCoverage(t *testing.T) { 15 | path := "./test" 16 | files, err := ioutil.ReadDir(path) 17 | if err != nil { 18 | t.Error(err) 19 | return 20 | } 21 | for _, f := range files { 22 | fmt.Printf("test sql file %s\n", f.Name()) 23 | if !strings.HasSuffix(f.Name(), ".sql") { 24 | continue 25 | } 26 | data, err := ioutil.ReadFile(filepath.Join(path, f.Name())) 27 | if err != nil { 28 | t.Error(err) 29 | return 30 | } 31 | query := string(data) 32 | stmts, err := Parser(query) 33 | if err != nil { 34 | t.Error(err) 35 | return 36 | } 37 | for _, stmt := range stmts { 38 | assert.NotNil(t, stmt) 39 | assert.Equal(t, len(stmt.Text()) > 0, true) 40 | } 41 | } 42 | } 43 | 44 | func TestSingleQuery(t *testing.T) { 45 | stmt, err := Parser(`create table db1.table1 (id number(10))`) 46 | assert.NoError(t, err) 47 | assert.Equal(t, 1, len(stmt)) 48 | assert.IsType(t, &ast.CreateTableStmt{}, stmt[0]) 49 | assert.Equal(t, `create table db1.table1 (id number(10))`, stmt[0].Text()) 50 | 51 | stmt, err = Parser(`create table db1.table1 (id number(10));`) 52 | assert.NoError(t, err) 53 | assert.Equal(t, 1, len(stmt)) 54 | assert.IsType(t, &ast.CreateTableStmt{}, stmt[0]) 55 | assert.Equal(t, `create table db1.table1 (id number(10));`, stmt[0].Text()) 56 | } 57 | 58 | func TestMultiQuery(t *testing.T) { 59 | stmt, err := Parser(`create table db1.table1 (id number(10)); 60 | alter table db1.table1 add (name varchar(255))`) 61 | assert.NoError(t, err) 62 | assert.Equal(t, 2, len(stmt)) 63 | assert.IsType(t, &ast.CreateTableStmt{}, stmt[0]) 64 | assert.Equal(t, "create table db1.table1 (id number(10));", stmt[0].Text()) 65 | assert.IsType(t, &ast.AlterTableStmt{}, stmt[1]) 66 | assert.Equal(t, "alter table db1.table1 add (name varchar(255))", stmt[1].Text()) 67 | 68 | stmt, err = Parser(`create table db1.table1 (id number(10)); 69 | alter table db1.table1 add (name varchar(255));`) 70 | assert.NoError(t, err) 71 | assert.Equal(t, 2, len(stmt)) 72 | assert.IsType(t, &ast.CreateTableStmt{}, stmt[0]) 73 | assert.Equal(t, "create table db1.table1 (id number(10));", stmt[0].Text()) 74 | assert.IsType(t, &ast.AlterTableStmt{}, stmt[1]) 75 | assert.Equal(t, "alter table db1.table1 add (name varchar(255));", stmt[1].Text()) 76 | } 77 | -------------------------------------------------------------------------------- /test/alter_table_add_column.sql: -------------------------------------------------------------------------------- 1 | alter table db1.table1 add (id number); 2 | 3 | alter table db1.table1 add (id number, name varchar(255)); 4 | 5 | alter table db1.table1 add (id number(*)); 6 | 7 | alter table db1.table1 add (id number(5)); 8 | 9 | alter table db1.table1 add (id number(5, 3)); 10 | 11 | alter table db1.table1 add (id float(*)); 12 | 13 | alter table db1.table1 add (id float(5)); 14 | 15 | alter table db1.table1 add (id varchar2(255)); 16 | 17 | alter table db1.table1 add (id varchar2(255) collate binary_ci); 18 | 19 | alter table db1.table1 add (id varchar2(255) sort); 20 | 21 | alter table db1.table1 add (id varchar2(255) collate binary_ci sort); 22 | 23 | alter table db1.table1 add (id varchar2(255) collate binary_ci invisible); 24 | 25 | alter table db1.table1 add (id varchar2(255) collate binary_ci visible); 26 | 27 | alter table db1.table1 add (id varchar2(255) collate binary_ci sort invisible); 28 | 29 | alter table db1.table1 add (id varchar2(255) default 'test'); 30 | 31 | alter table db1.table1 add (id number default 123); 32 | 33 | alter table db1.table1 add (id number not null, name varchar(255) unique); 34 | -------------------------------------------------------------------------------- /test/alter_table_constraint.sql: -------------------------------------------------------------------------------- 1 | alter table db1.table1 add primary key(id); 2 | 3 | alter table db1.table1 drop primary key; 4 | 5 | alter table db1.table1 drop unique(name,age); 6 | 7 | alter table db1.table1 drop constraint idx_1; 8 | 9 | alter table db1.table1 drop primary key drop unique(name,age); 10 | 11 | alter table db1.table1 drop primary key drop unique(name,age) drop constraint idx_1; 12 | 13 | alter table db1.table1 rename constraint idx_1 to idx_2; 14 | 15 | alter table db1.table1 modify primary key using index; 16 | 17 | alter table db1.table1 modify primary key rely using index idx_1 enable validate; 18 | 19 | alter table db1.table1 modify constraint idx_1 using index; 20 | 21 | alter table db1.table1 modify unique(name,age) using index; 22 | 23 | alter table db1.table1 drop primary key keep index; 24 | 25 | alter table db1.table1 drop primary key keep index drop unique(name,age) drop index; -------------------------------------------------------------------------------- /test/alter_table_drop_column.sql: -------------------------------------------------------------------------------- 1 | alter table db1.table1 drop column id; 2 | 3 | alter table db1.table1 drop (id,name); 4 | 5 | alter table db1.table1 set unused column id; -------------------------------------------------------------------------------- /test/alter_table_modify_column.sql: -------------------------------------------------------------------------------- 1 | alter table db1.table1 modify (id varchar2(255)); 2 | 3 | alter table db1.table1 modify (id varchar2(255) default '123'); 4 | 5 | alter table db1.table1 modify (id varchar2(255) unique); -------------------------------------------------------------------------------- /test/alter_table_rename.sql: -------------------------------------------------------------------------------- 1 | alter table db1.table1 rename column id to new_id; -------------------------------------------------------------------------------- /test/create_index.sql: -------------------------------------------------------------------------------- 1 | create index db1.idx1 on db1.table1 (id); 2 | 3 | CREATE UNIQUE INDEX "TEST"."SYS_C00385176" on "TEST"."SBTEST1"("ID") NOPARALLEL; -------------------------------------------------------------------------------- /test/create_table.sql: -------------------------------------------------------------------------------- 1 | create table db1.table1 (id number(10));create table db1.table1 (id number(10), name varchar2(255)); 2 | 3 | CREATE TABLE "TEST"."T1" 4 | ( 5 | "ID" NUMBER(*,0) 6 | ) SEGMENT CREATION IMMEDIATE PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING 7 | STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 8 | PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) 9 | TABLESPACE "SYSTEM"; 10 | 11 | create table db1.table1 (id number(10) primary key); 12 | 13 | create table db1.table1 (id number(10), unique (id) enable); 14 | 15 | create table db1.table1 (id number(10), primary key (id) enable); 16 | 17 | create table db1.table1 (id number(10), CONSTRAINT pk primary key (id) enable); 18 | 19 | create table db1.table1 (id number(10), primary key (id) using index enable); 20 | 21 | create table db1.table1 (id number(10,3) primary key); 22 | 23 | CREATE TABLE test."persons" ( NUMERIC_NAME NUMERIC ( 15, 2 ), Decimal_NAME DECIMAL ( 15, 2 ), Dec_NAME DEC ( 15, 2 ), INTEGER_NAME INTEGER ); 24 | 25 | create table TEST.T21 (t CHAR(255)); 26 | 27 | create table TEST.T21 (t character(255)); 28 | 29 | CREATE TABLE TEST.INTERVAL_YEAR_COLUMNS(ID INT, C_INTERVAL_YEAR INTERVAL YEAR TO MONTH); 30 | 31 | CREATE TABLE TEST.INTERVAL_YEAR_COLUMNS(ID INT, C_INTERVAL_YEAR INTERVAL YEAR(3) TO MONTH); 32 | 33 | create table db1.table1 (primary varchar(255)); 34 | 35 | create table db1.table1 (id int, xml_data XMLTYPE); 36 | 37 | create table db1.table1 (id int unique not deferrable not null); 38 | 39 | create table db1.table1 (id int) organization heap no inmemory; 40 | 41 | create table db1.table1 (id int) organization heap inmemory no memcompress no duplicate; 42 | 43 | create table db1.table1 (id number(10), CONSTRAINT pk primary key (id) not deferrable initially deferred); 44 | 45 | create table db1.table1 (id number(10), CONSTRAINT pk primary key (id) initially deferred not deferrable); 46 | 47 | create table db1.table1 (id number(10) not null); 48 | 49 | create table db1.table1 (id number(10) not null unique); 50 | 51 | create table db1.table1 (id number(10) unique not null); 52 | 53 | create table db1.table1 (id number(10) unique not deferrable not null); 54 | 55 | create table db1.table1 (id number(10) unique not 56 | deferrable not null); 57 | 58 | create table db1.table1 (id number(10) unique not 59 | deferrable not null); 60 | 61 | create table db1.table1 (start_time timestamp(5)); 62 | 63 | CREATE TABLE sbtest1 ( 64 | id INTEGER NOT NULL, 65 | k INTEGER, 66 | c CHAR(120) DEFAULT '' NOT NULL, 67 | pad CHAR(60) DEFAULT '' NOT NULL, 68 | PRIMARY KEY (id) 69 | ); 70 | 71 | create table db1.table_1 (id_1 int); 72 | create table db1.table#1 (id#1 int); 73 | create table db1.table$1 (id$1 int); 74 | create table db1.table$#_1 (id$1_ int); 75 | 76 | create table db1.table1 (ts TIMESTAMP); 77 | create table db1.table1 (ts TIMESTAMP(6)); 78 | create table db1.table1 (ts TIMESTAMP WITH TIME ZONE); 79 | create table db1.table1 (ts TIMESTAMP WITH LOCAL TIME ZONE); 80 | create table db1.table1 (ts TIMESTAMP(6) WITH TIME ZONE); 81 | create table db1.table1 (ts TIMESTAMP(6) WITH LOCAL TIME ZONE); -------------------------------------------------------------------------------- /test/drop_index.sql: -------------------------------------------------------------------------------- 1 | drop index idx_1; 2 | 3 | drop index db1.idx_1; 4 | 5 | drop index db1.idx_1 online; 6 | 7 | drop index db1.idx_1 online force; -------------------------------------------------------------------------------- /test/drop_table.sql: -------------------------------------------------------------------------------- 1 | drop table db1.table1; 2 | 3 | drop table table1; 4 | 5 | drop table db1.table1 cascade constraints purge; 6 | 7 | drop table table1 cascade constraints; 8 | 9 | drop table db1.table1 purge; -------------------------------------------------------------------------------- /test/test_comments.sql: -------------------------------------------------------------------------------- 1 | --comment 2 | CREATE TABLE db1.t1 ( 3 | id int, -- comment 4 | name varchar2(255) -- comment comment 5 | ); -- !@#$%^&*( 6 | 7 | /* 8 | comment comment comment 9 | */ 10 | CREATE TABLE db1.t1 ( 11 | /* comment */ 12 | id int, 13 | name varchar2(255) 14 | ); 15 | 16 | /* 17 | comment comment comment 18 | */ 19 | CREATE TABLE db1.t1 ( 20 | /* comment */ 21 | id int, -- comment 22 | name varchar2(255) -- comment comment 23 | ); -- !@#$%^&*( -------------------------------------------------------------------------------- /vendor/github.com/davecgh/go-spew/LICENSE: -------------------------------------------------------------------------------- 1 | ISC License 2 | 3 | Copyright (c) 2012-2016 Dave Collins 4 | 5 | Permission to use, copy, modify, and distribute this software for any 6 | purpose with or without fee is hereby granted, provided that the above 7 | copyright notice and this permission notice appear in all copies. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | -------------------------------------------------------------------------------- /vendor/github.com/davecgh/go-spew/spew/bypass.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016 Dave Collins 2 | // 3 | // Permission to use, copy, modify, and distribute this software for any 4 | // purpose with or without fee is hereby granted, provided that the above 5 | // copyright notice and this permission notice appear in all copies. 6 | // 7 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 | 15 | // NOTE: Due to the following build constraints, this file will only be compiled 16 | // when the code is not running on Google App Engine, compiled by GopherJS, and 17 | // "-tags safe" is not added to the go build command line. The "disableunsafe" 18 | // tag is deprecated and thus should not be used. 19 | // +build !js,!appengine,!safe,!disableunsafe 20 | 21 | package spew 22 | 23 | import ( 24 | "reflect" 25 | "unsafe" 26 | ) 27 | 28 | const ( 29 | // UnsafeDisabled is a build-time constant which specifies whether or 30 | // not access to the unsafe package is available. 31 | UnsafeDisabled = false 32 | 33 | // ptrSize is the size of a pointer on the current arch. 34 | ptrSize = unsafe.Sizeof((*byte)(nil)) 35 | ) 36 | 37 | var ( 38 | // offsetPtr, offsetScalar, and offsetFlag are the offsets for the 39 | // internal reflect.Value fields. These values are valid before golang 40 | // commit ecccf07e7f9d which changed the format. The are also valid 41 | // after commit 82f48826c6c7 which changed the format again to mirror 42 | // the original format. Code in the init function updates these offsets 43 | // as necessary. 44 | offsetPtr = uintptr(ptrSize) 45 | offsetScalar = uintptr(0) 46 | offsetFlag = uintptr(ptrSize * 2) 47 | 48 | // flagKindWidth and flagKindShift indicate various bits that the 49 | // reflect package uses internally to track kind information. 50 | // 51 | // flagRO indicates whether or not the value field of a reflect.Value is 52 | // read-only. 53 | // 54 | // flagIndir indicates whether the value field of a reflect.Value is 55 | // the actual data or a pointer to the data. 56 | // 57 | // These values are valid before golang commit 90a7c3c86944 which 58 | // changed their positions. Code in the init function updates these 59 | // flags as necessary. 60 | flagKindWidth = uintptr(5) 61 | flagKindShift = uintptr(flagKindWidth - 1) 62 | flagRO = uintptr(1 << 0) 63 | flagIndir = uintptr(1 << 1) 64 | ) 65 | 66 | func init() { 67 | // Older versions of reflect.Value stored small integers directly in the 68 | // ptr field (which is named val in the older versions). Versions 69 | // between commits ecccf07e7f9d and 82f48826c6c7 added a new field named 70 | // scalar for this purpose which unfortunately came before the flag 71 | // field, so the offset of the flag field is different for those 72 | // versions. 73 | // 74 | // This code constructs a new reflect.Value from a known small integer 75 | // and checks if the size of the reflect.Value struct indicates it has 76 | // the scalar field. When it does, the offsets are updated accordingly. 77 | vv := reflect.ValueOf(0xf00) 78 | if unsafe.Sizeof(vv) == (ptrSize * 4) { 79 | offsetScalar = ptrSize * 2 80 | offsetFlag = ptrSize * 3 81 | } 82 | 83 | // Commit 90a7c3c86944 changed the flag positions such that the low 84 | // order bits are the kind. This code extracts the kind from the flags 85 | // field and ensures it's the correct type. When it's not, the flag 86 | // order has been changed to the newer format, so the flags are updated 87 | // accordingly. 88 | upf := unsafe.Pointer(uintptr(unsafe.Pointer(&vv)) + offsetFlag) 89 | upfv := *(*uintptr)(upf) 90 | flagKindMask := uintptr((1<>flagKindShift != uintptr(reflect.Int) { 92 | flagKindShift = 0 93 | flagRO = 1 << 5 94 | flagIndir = 1 << 6 95 | 96 | // Commit adf9b30e5594 modified the flags to separate the 97 | // flagRO flag into two bits which specifies whether or not the 98 | // field is embedded. This causes flagIndir to move over a bit 99 | // and means that flagRO is the combination of either of the 100 | // original flagRO bit and the new bit. 101 | // 102 | // This code detects the change by extracting what used to be 103 | // the indirect bit to ensure it's set. When it's not, the flag 104 | // order has been changed to the newer format, so the flags are 105 | // updated accordingly. 106 | if upfv&flagIndir == 0 { 107 | flagRO = 3 << 5 108 | flagIndir = 1 << 7 109 | } 110 | } 111 | } 112 | 113 | // unsafeReflectValue converts the passed reflect.Value into a one that bypasses 114 | // the typical safety restrictions preventing access to unaddressable and 115 | // unexported data. It works by digging the raw pointer to the underlying 116 | // value out of the protected value and generating a new unprotected (unsafe) 117 | // reflect.Value to it. 118 | // 119 | // This allows us to check for implementations of the Stringer and error 120 | // interfaces to be used for pretty printing ordinarily unaddressable and 121 | // inaccessible values such as unexported struct fields. 122 | func unsafeReflectValue(v reflect.Value) (rv reflect.Value) { 123 | indirects := 1 124 | vt := v.Type() 125 | upv := unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetPtr) 126 | rvf := *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetFlag)) 127 | if rvf&flagIndir != 0 { 128 | vt = reflect.PtrTo(v.Type()) 129 | indirects++ 130 | } else if offsetScalar != 0 { 131 | // The value is in the scalar field when it's not one of the 132 | // reference types. 133 | switch vt.Kind() { 134 | case reflect.Uintptr: 135 | case reflect.Chan: 136 | case reflect.Func: 137 | case reflect.Map: 138 | case reflect.Ptr: 139 | case reflect.UnsafePointer: 140 | default: 141 | upv = unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + 142 | offsetScalar) 143 | } 144 | } 145 | 146 | pv := reflect.NewAt(vt, upv) 147 | rv = pv 148 | for i := 0; i < indirects; i++ { 149 | rv = rv.Elem() 150 | } 151 | return rv 152 | } 153 | -------------------------------------------------------------------------------- /vendor/github.com/davecgh/go-spew/spew/bypasssafe.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-2016 Dave Collins 2 | // 3 | // Permission to use, copy, modify, and distribute this software for any 4 | // purpose with or without fee is hereby granted, provided that the above 5 | // copyright notice and this permission notice appear in all copies. 6 | // 7 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 | 15 | // NOTE: Due to the following build constraints, this file will only be compiled 16 | // when the code is running on Google App Engine, compiled by GopherJS, or 17 | // "-tags safe" is added to the go build command line. The "disableunsafe" 18 | // tag is deprecated and thus should not be used. 19 | // +build js appengine safe disableunsafe 20 | 21 | package spew 22 | 23 | import "reflect" 24 | 25 | const ( 26 | // UnsafeDisabled is a build-time constant which specifies whether or 27 | // not access to the unsafe package is available. 28 | UnsafeDisabled = true 29 | ) 30 | 31 | // unsafeReflectValue typically converts the passed reflect.Value into a one 32 | // that bypasses the typical safety restrictions preventing access to 33 | // unaddressable and unexported data. However, doing this relies on access to 34 | // the unsafe package. This is a stub version which simply returns the passed 35 | // reflect.Value when the unsafe package is not available. 36 | func unsafeReflectValue(v reflect.Value) reflect.Value { 37 | return v 38 | } 39 | -------------------------------------------------------------------------------- /vendor/github.com/davecgh/go-spew/spew/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2016 Dave Collins 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | /* 18 | Package spew implements a deep pretty printer for Go data structures to aid in 19 | debugging. 20 | 21 | A quick overview of the additional features spew provides over the built-in 22 | printing facilities for Go data types are as follows: 23 | 24 | * Pointers are dereferenced and followed 25 | * Circular data structures are detected and handled properly 26 | * Custom Stringer/error interfaces are optionally invoked, including 27 | on unexported types 28 | * Custom types which only implement the Stringer/error interfaces via 29 | a pointer receiver are optionally invoked when passing non-pointer 30 | variables 31 | * Byte arrays and slices are dumped like the hexdump -C command which 32 | includes offsets, byte values in hex, and ASCII output (only when using 33 | Dump style) 34 | 35 | There are two different approaches spew allows for dumping Go data structures: 36 | 37 | * Dump style which prints with newlines, customizable indentation, 38 | and additional debug information such as types and all pointer addresses 39 | used to indirect to the final value 40 | * A custom Formatter interface that integrates cleanly with the standard fmt 41 | package and replaces %v, %+v, %#v, and %#+v to provide inline printing 42 | similar to the default %v while providing the additional functionality 43 | outlined above and passing unsupported format verbs such as %x and %q 44 | along to fmt 45 | 46 | Quick Start 47 | 48 | This section demonstrates how to quickly get started with spew. See the 49 | sections below for further details on formatting and configuration options. 50 | 51 | To dump a variable with full newlines, indentation, type, and pointer 52 | information use Dump, Fdump, or Sdump: 53 | spew.Dump(myVar1, myVar2, ...) 54 | spew.Fdump(someWriter, myVar1, myVar2, ...) 55 | str := spew.Sdump(myVar1, myVar2, ...) 56 | 57 | Alternatively, if you would prefer to use format strings with a compacted inline 58 | printing style, use the convenience wrappers Printf, Fprintf, etc with 59 | %v (most compact), %+v (adds pointer addresses), %#v (adds types), or 60 | %#+v (adds types and pointer addresses): 61 | spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2) 62 | spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) 63 | spew.Fprintf(someWriter, "myVar1: %v -- myVar2: %+v", myVar1, myVar2) 64 | spew.Fprintf(someWriter, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) 65 | 66 | Configuration Options 67 | 68 | Configuration of spew is handled by fields in the ConfigState type. For 69 | convenience, all of the top-level functions use a global state available 70 | via the spew.Config global. 71 | 72 | It is also possible to create a ConfigState instance that provides methods 73 | equivalent to the top-level functions. This allows concurrent configuration 74 | options. See the ConfigState documentation for more details. 75 | 76 | The following configuration options are available: 77 | * Indent 78 | String to use for each indentation level for Dump functions. 79 | It is a single space by default. A popular alternative is "\t". 80 | 81 | * MaxDepth 82 | Maximum number of levels to descend into nested data structures. 83 | There is no limit by default. 84 | 85 | * DisableMethods 86 | Disables invocation of error and Stringer interface methods. 87 | Method invocation is enabled by default. 88 | 89 | * DisablePointerMethods 90 | Disables invocation of error and Stringer interface methods on types 91 | which only accept pointer receivers from non-pointer variables. 92 | Pointer method invocation is enabled by default. 93 | 94 | * DisablePointerAddresses 95 | DisablePointerAddresses specifies whether to disable the printing of 96 | pointer addresses. This is useful when diffing data structures in tests. 97 | 98 | * DisableCapacities 99 | DisableCapacities specifies whether to disable the printing of 100 | capacities for arrays, slices, maps and channels. This is useful when 101 | diffing data structures in tests. 102 | 103 | * ContinueOnMethod 104 | Enables recursion into types after invoking error and Stringer interface 105 | methods. Recursion after method invocation is disabled by default. 106 | 107 | * SortKeys 108 | Specifies map keys should be sorted before being printed. Use 109 | this to have a more deterministic, diffable output. Note that 110 | only native types (bool, int, uint, floats, uintptr and string) 111 | and types which implement error or Stringer interfaces are 112 | supported with other types sorted according to the 113 | reflect.Value.String() output which guarantees display 114 | stability. Natural map order is used by default. 115 | 116 | * SpewKeys 117 | Specifies that, as a last resort attempt, map keys should be 118 | spewed to strings and sorted by those strings. This is only 119 | considered if SortKeys is true. 120 | 121 | Dump Usage 122 | 123 | Simply call spew.Dump with a list of variables you want to dump: 124 | 125 | spew.Dump(myVar1, myVar2, ...) 126 | 127 | You may also call spew.Fdump if you would prefer to output to an arbitrary 128 | io.Writer. For example, to dump to standard error: 129 | 130 | spew.Fdump(os.Stderr, myVar1, myVar2, ...) 131 | 132 | A third option is to call spew.Sdump to get the formatted output as a string: 133 | 134 | str := spew.Sdump(myVar1, myVar2, ...) 135 | 136 | Sample Dump Output 137 | 138 | See the Dump example for details on the setup of the types and variables being 139 | shown here. 140 | 141 | (main.Foo) { 142 | unexportedField: (*main.Bar)(0xf84002e210)({ 143 | flag: (main.Flag) flagTwo, 144 | data: (uintptr) 145 | }), 146 | ExportedField: (map[interface {}]interface {}) (len=1) { 147 | (string) (len=3) "one": (bool) true 148 | } 149 | } 150 | 151 | Byte (and uint8) arrays and slices are displayed uniquely like the hexdump -C 152 | command as shown. 153 | ([]uint8) (len=32 cap=32) { 154 | 00000000 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 |............... | 155 | 00000010 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 |!"#$%&'()*+,-./0| 156 | 00000020 31 32 |12| 157 | } 158 | 159 | Custom Formatter 160 | 161 | Spew provides a custom formatter that implements the fmt.Formatter interface 162 | so that it integrates cleanly with standard fmt package printing functions. The 163 | formatter is useful for inline printing of smaller data types similar to the 164 | standard %v format specifier. 165 | 166 | The custom formatter only responds to the %v (most compact), %+v (adds pointer 167 | addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb 168 | combinations. Any other verbs such as %x and %q will be sent to the the 169 | standard fmt package for formatting. In addition, the custom formatter ignores 170 | the width and precision arguments (however they will still work on the format 171 | specifiers not handled by the custom formatter). 172 | 173 | Custom Formatter Usage 174 | 175 | The simplest way to make use of the spew custom formatter is to call one of the 176 | convenience functions such as spew.Printf, spew.Println, or spew.Printf. The 177 | functions have syntax you are most likely already familiar with: 178 | 179 | spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2) 180 | spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) 181 | spew.Println(myVar, myVar2) 182 | spew.Fprintf(os.Stderr, "myVar1: %v -- myVar2: %+v", myVar1, myVar2) 183 | spew.Fprintf(os.Stderr, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) 184 | 185 | See the Index for the full list convenience functions. 186 | 187 | Sample Formatter Output 188 | 189 | Double pointer to a uint8: 190 | %v: <**>5 191 | %+v: <**>(0xf8400420d0->0xf8400420c8)5 192 | %#v: (**uint8)5 193 | %#+v: (**uint8)(0xf8400420d0->0xf8400420c8)5 194 | 195 | Pointer to circular struct with a uint8 field and a pointer to itself: 196 | %v: <*>{1 <*>} 197 | %+v: <*>(0xf84003e260){ui8:1 c:<*>(0xf84003e260)} 198 | %#v: (*main.circular){ui8:(uint8)1 c:(*main.circular)} 199 | %#+v: (*main.circular)(0xf84003e260){ui8:(uint8)1 c:(*main.circular)(0xf84003e260)} 200 | 201 | See the Printf example for details on the setup of variables being shown 202 | here. 203 | 204 | Errors 205 | 206 | Since it is possible for custom Stringer/error interfaces to panic, spew 207 | detects them and handles them internally by printing the panic information 208 | inline with the output. Since spew is intended to provide deep pretty printing 209 | capabilities on structures, it intentionally does not return any errors. 210 | */ 211 | package spew 212 | -------------------------------------------------------------------------------- /vendor/github.com/davecgh/go-spew/spew/spew.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2016 Dave Collins 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | package spew 18 | 19 | import ( 20 | "fmt" 21 | "io" 22 | ) 23 | 24 | // Errorf is a wrapper for fmt.Errorf that treats each argument as if it were 25 | // passed with a default Formatter interface returned by NewFormatter. It 26 | // returns the formatted string as a value that satisfies error. See 27 | // NewFormatter for formatting details. 28 | // 29 | // This function is shorthand for the following syntax: 30 | // 31 | // fmt.Errorf(format, spew.NewFormatter(a), spew.NewFormatter(b)) 32 | func Errorf(format string, a ...interface{}) (err error) { 33 | return fmt.Errorf(format, convertArgs(a)...) 34 | } 35 | 36 | // Fprint is a wrapper for fmt.Fprint that treats each argument as if it were 37 | // passed with a default Formatter interface returned by NewFormatter. It 38 | // returns the number of bytes written and any write error encountered. See 39 | // NewFormatter for formatting details. 40 | // 41 | // This function is shorthand for the following syntax: 42 | // 43 | // fmt.Fprint(w, spew.NewFormatter(a), spew.NewFormatter(b)) 44 | func Fprint(w io.Writer, a ...interface{}) (n int, err error) { 45 | return fmt.Fprint(w, convertArgs(a)...) 46 | } 47 | 48 | // Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were 49 | // passed with a default Formatter interface returned by NewFormatter. It 50 | // returns the number of bytes written and any write error encountered. See 51 | // NewFormatter for formatting details. 52 | // 53 | // This function is shorthand for the following syntax: 54 | // 55 | // fmt.Fprintf(w, format, spew.NewFormatter(a), spew.NewFormatter(b)) 56 | func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) { 57 | return fmt.Fprintf(w, format, convertArgs(a)...) 58 | } 59 | 60 | // Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it 61 | // passed with a default Formatter interface returned by NewFormatter. See 62 | // NewFormatter for formatting details. 63 | // 64 | // This function is shorthand for the following syntax: 65 | // 66 | // fmt.Fprintln(w, spew.NewFormatter(a), spew.NewFormatter(b)) 67 | func Fprintln(w io.Writer, a ...interface{}) (n int, err error) { 68 | return fmt.Fprintln(w, convertArgs(a)...) 69 | } 70 | 71 | // Print is a wrapper for fmt.Print that treats each argument as if it were 72 | // passed with a default Formatter interface returned by NewFormatter. It 73 | // returns the number of bytes written and any write error encountered. See 74 | // NewFormatter for formatting details. 75 | // 76 | // This function is shorthand for the following syntax: 77 | // 78 | // fmt.Print(spew.NewFormatter(a), spew.NewFormatter(b)) 79 | func Print(a ...interface{}) (n int, err error) { 80 | return fmt.Print(convertArgs(a)...) 81 | } 82 | 83 | // Printf is a wrapper for fmt.Printf that treats each argument as if it were 84 | // passed with a default Formatter interface returned by NewFormatter. It 85 | // returns the number of bytes written and any write error encountered. See 86 | // NewFormatter for formatting details. 87 | // 88 | // This function is shorthand for the following syntax: 89 | // 90 | // fmt.Printf(format, spew.NewFormatter(a), spew.NewFormatter(b)) 91 | func Printf(format string, a ...interface{}) (n int, err error) { 92 | return fmt.Printf(format, convertArgs(a)...) 93 | } 94 | 95 | // Println is a wrapper for fmt.Println that treats each argument as if it were 96 | // passed with a default Formatter interface returned by NewFormatter. It 97 | // returns the number of bytes written and any write error encountered. See 98 | // NewFormatter for formatting details. 99 | // 100 | // This function is shorthand for the following syntax: 101 | // 102 | // fmt.Println(spew.NewFormatter(a), spew.NewFormatter(b)) 103 | func Println(a ...interface{}) (n int, err error) { 104 | return fmt.Println(convertArgs(a)...) 105 | } 106 | 107 | // Sprint is a wrapper for fmt.Sprint that treats each argument as if it were 108 | // passed with a default Formatter interface returned by NewFormatter. It 109 | // returns the resulting string. See NewFormatter for formatting details. 110 | // 111 | // This function is shorthand for the following syntax: 112 | // 113 | // fmt.Sprint(spew.NewFormatter(a), spew.NewFormatter(b)) 114 | func Sprint(a ...interface{}) string { 115 | return fmt.Sprint(convertArgs(a)...) 116 | } 117 | 118 | // Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were 119 | // passed with a default Formatter interface returned by NewFormatter. It 120 | // returns the resulting string. See NewFormatter for formatting details. 121 | // 122 | // This function is shorthand for the following syntax: 123 | // 124 | // fmt.Sprintf(format, spew.NewFormatter(a), spew.NewFormatter(b)) 125 | func Sprintf(format string, a ...interface{}) string { 126 | return fmt.Sprintf(format, convertArgs(a)...) 127 | } 128 | 129 | // Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it 130 | // were passed with a default Formatter interface returned by NewFormatter. It 131 | // returns the resulting string. See NewFormatter for formatting details. 132 | // 133 | // This function is shorthand for the following syntax: 134 | // 135 | // fmt.Sprintln(spew.NewFormatter(a), spew.NewFormatter(b)) 136 | func Sprintln(a ...interface{}) string { 137 | return fmt.Sprintln(convertArgs(a)...) 138 | } 139 | 140 | // convertArgs accepts a slice of arguments and returns a slice of the same 141 | // length with each argument converted to a default spew Formatter interface. 142 | func convertArgs(args []interface{}) (formatters []interface{}) { 143 | formatters = make([]interface{}, len(args)) 144 | for index, arg := range args { 145 | formatters[index] = NewFormatter(arg) 146 | } 147 | return formatters 148 | } 149 | -------------------------------------------------------------------------------- /vendor/github.com/pmezard/go-difflib/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013, Patrick Mezard 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | The names of its contributors may not be used to endorse or promote 14 | products derived from this software without specific prior written 15 | permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 18 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 19 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 20 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 23 | TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 24 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 25 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 26 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/testify/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2012-2020 Mat Ryer, Tyler Bunnell and contributors. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/testify/assert/assertion_format.go.tmpl: -------------------------------------------------------------------------------- 1 | {{.CommentFormat}} 2 | func {{.DocInfo.Name}}f(t TestingT, {{.ParamsFormat}}) bool { 3 | if h, ok := t.(tHelper); ok { h.Helper() } 4 | return {{.DocInfo.Name}}(t, {{.ForwardedParamsFormat}}) 5 | } 6 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/testify/assert/assertion_forward.go.tmpl: -------------------------------------------------------------------------------- 1 | {{.CommentWithoutT "a"}} 2 | func (a *Assertions) {{.DocInfo.Name}}({{.Params}}) bool { 3 | if h, ok := a.t.(tHelper); ok { h.Helper() } 4 | return {{.DocInfo.Name}}(a.t, {{.ForwardedParams}}) 5 | } 6 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/testify/assert/assertion_order.go: -------------------------------------------------------------------------------- 1 | package assert 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | ) 7 | 8 | // isOrdered checks that collection contains orderable elements. 9 | func isOrdered(t TestingT, object interface{}, allowedComparesResults []CompareType, failMessage string, msgAndArgs ...interface{}) bool { 10 | objKind := reflect.TypeOf(object).Kind() 11 | if objKind != reflect.Slice && objKind != reflect.Array { 12 | return false 13 | } 14 | 15 | objValue := reflect.ValueOf(object) 16 | objLen := objValue.Len() 17 | 18 | if objLen <= 1 { 19 | return true 20 | } 21 | 22 | value := objValue.Index(0) 23 | valueInterface := value.Interface() 24 | firstValueKind := value.Kind() 25 | 26 | for i := 1; i < objLen; i++ { 27 | prevValue := value 28 | prevValueInterface := valueInterface 29 | 30 | value = objValue.Index(i) 31 | valueInterface = value.Interface() 32 | 33 | compareResult, isComparable := compare(prevValueInterface, valueInterface, firstValueKind) 34 | 35 | if !isComparable { 36 | return Fail(t, fmt.Sprintf("Can not compare type \"%s\" and \"%s\"", reflect.TypeOf(value), reflect.TypeOf(prevValue)), msgAndArgs...) 37 | } 38 | 39 | if !containsValue(allowedComparesResults, compareResult) { 40 | return Fail(t, fmt.Sprintf(failMessage, prevValue, value), msgAndArgs...) 41 | } 42 | } 43 | 44 | return true 45 | } 46 | 47 | // IsIncreasing asserts that the collection is increasing 48 | // 49 | // assert.IsIncreasing(t, []int{1, 2, 3}) 50 | // assert.IsIncreasing(t, []float{1, 2}) 51 | // assert.IsIncreasing(t, []string{"a", "b"}) 52 | func IsIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { 53 | return isOrdered(t, object, []CompareType{compareLess}, "\"%v\" is not less than \"%v\"", msgAndArgs) 54 | } 55 | 56 | // IsNonIncreasing asserts that the collection is not increasing 57 | // 58 | // assert.IsNonIncreasing(t, []int{2, 1, 1}) 59 | // assert.IsNonIncreasing(t, []float{2, 1}) 60 | // assert.IsNonIncreasing(t, []string{"b", "a"}) 61 | func IsNonIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { 62 | return isOrdered(t, object, []CompareType{compareEqual, compareGreater}, "\"%v\" is not greater than or equal to \"%v\"", msgAndArgs) 63 | } 64 | 65 | // IsDecreasing asserts that the collection is decreasing 66 | // 67 | // assert.IsDecreasing(t, []int{2, 1, 0}) 68 | // assert.IsDecreasing(t, []float{2, 1}) 69 | // assert.IsDecreasing(t, []string{"b", "a"}) 70 | func IsDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { 71 | return isOrdered(t, object, []CompareType{compareGreater}, "\"%v\" is not greater than \"%v\"", msgAndArgs) 72 | } 73 | 74 | // IsNonDecreasing asserts that the collection is not decreasing 75 | // 76 | // assert.IsNonDecreasing(t, []int{1, 1, 2}) 77 | // assert.IsNonDecreasing(t, []float{1, 2}) 78 | // assert.IsNonDecreasing(t, []string{"a", "b"}) 79 | func IsNonDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { 80 | return isOrdered(t, object, []CompareType{compareLess, compareEqual}, "\"%v\" is not less than or equal to \"%v\"", msgAndArgs) 81 | } 82 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/testify/assert/doc.go: -------------------------------------------------------------------------------- 1 | // Package assert provides a set of comprehensive testing tools for use with the normal Go testing system. 2 | // 3 | // Example Usage 4 | // 5 | // The following is a complete example using assert in a standard test function: 6 | // import ( 7 | // "testing" 8 | // "github.com/stretchr/testify/assert" 9 | // ) 10 | // 11 | // func TestSomething(t *testing.T) { 12 | // 13 | // var a string = "Hello" 14 | // var b string = "Hello" 15 | // 16 | // assert.Equal(t, a, b, "The two words should be the same.") 17 | // 18 | // } 19 | // 20 | // if you assert many times, use the format below: 21 | // 22 | // import ( 23 | // "testing" 24 | // "github.com/stretchr/testify/assert" 25 | // ) 26 | // 27 | // func TestSomething(t *testing.T) { 28 | // assert := assert.New(t) 29 | // 30 | // var a string = "Hello" 31 | // var b string = "Hello" 32 | // 33 | // assert.Equal(a, b, "The two words should be the same.") 34 | // } 35 | // 36 | // Assertions 37 | // 38 | // Assertions allow you to easily write test code, and are global funcs in the `assert` package. 39 | // All assertion functions take, as the first argument, the `*testing.T` object provided by the 40 | // testing framework. This allows the assertion funcs to write the failings and other details to 41 | // the correct place. 42 | // 43 | // Every assertion function also takes an optional string message as the final argument, 44 | // allowing custom error messages to be appended to the message the assertion method outputs. 45 | package assert 46 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/testify/assert/errors.go: -------------------------------------------------------------------------------- 1 | package assert 2 | 3 | import ( 4 | "errors" 5 | ) 6 | 7 | // AnError is an error instance useful for testing. If the code does not care 8 | // about error specifics, and only needs to return the error for example, this 9 | // error should be used to make the test code more readable. 10 | var AnError = errors.New("assert.AnError general error for testing") 11 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/testify/assert/forward_assertions.go: -------------------------------------------------------------------------------- 1 | package assert 2 | 3 | // Assertions provides assertion methods around the 4 | // TestingT interface. 5 | type Assertions struct { 6 | t TestingT 7 | } 8 | 9 | // New makes a new Assertions object for the specified TestingT. 10 | func New(t TestingT) *Assertions { 11 | return &Assertions{ 12 | t: t, 13 | } 14 | } 15 | 16 | //go:generate sh -c "cd ../_codegen && go build && cd - && ../_codegen/_codegen -output-package=assert -template=assertion_forward.go.tmpl -include-format-funcs" 17 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/testify/assert/http_assertions.go: -------------------------------------------------------------------------------- 1 | package assert 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "net/http/httptest" 7 | "net/url" 8 | "strings" 9 | ) 10 | 11 | // httpCode is a helper that returns HTTP code of the response. It returns -1 and 12 | // an error if building a new request fails. 13 | func httpCode(handler http.HandlerFunc, method, url string, values url.Values) (int, error) { 14 | w := httptest.NewRecorder() 15 | req, err := http.NewRequest(method, url, nil) 16 | if err != nil { 17 | return -1, err 18 | } 19 | req.URL.RawQuery = values.Encode() 20 | handler(w, req) 21 | return w.Code, nil 22 | } 23 | 24 | // HTTPSuccess asserts that a specified handler returns a success status code. 25 | // 26 | // assert.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil) 27 | // 28 | // Returns whether the assertion was successful (true) or not (false). 29 | func HTTPSuccess(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool { 30 | if h, ok := t.(tHelper); ok { 31 | h.Helper() 32 | } 33 | code, err := httpCode(handler, method, url, values) 34 | if err != nil { 35 | Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err)) 36 | } 37 | 38 | isSuccessCode := code >= http.StatusOK && code <= http.StatusPartialContent 39 | if !isSuccessCode { 40 | Fail(t, fmt.Sprintf("Expected HTTP success status code for %q but received %d", url+"?"+values.Encode(), code)) 41 | } 42 | 43 | return isSuccessCode 44 | } 45 | 46 | // HTTPRedirect asserts that a specified handler returns a redirect status code. 47 | // 48 | // assert.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} 49 | // 50 | // Returns whether the assertion was successful (true) or not (false). 51 | func HTTPRedirect(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool { 52 | if h, ok := t.(tHelper); ok { 53 | h.Helper() 54 | } 55 | code, err := httpCode(handler, method, url, values) 56 | if err != nil { 57 | Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err)) 58 | } 59 | 60 | isRedirectCode := code >= http.StatusMultipleChoices && code <= http.StatusTemporaryRedirect 61 | if !isRedirectCode { 62 | Fail(t, fmt.Sprintf("Expected HTTP redirect status code for %q but received %d", url+"?"+values.Encode(), code)) 63 | } 64 | 65 | return isRedirectCode 66 | } 67 | 68 | // HTTPError asserts that a specified handler returns an error status code. 69 | // 70 | // assert.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} 71 | // 72 | // Returns whether the assertion was successful (true) or not (false). 73 | func HTTPError(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool { 74 | if h, ok := t.(tHelper); ok { 75 | h.Helper() 76 | } 77 | code, err := httpCode(handler, method, url, values) 78 | if err != nil { 79 | Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err)) 80 | } 81 | 82 | isErrorCode := code >= http.StatusBadRequest 83 | if !isErrorCode { 84 | Fail(t, fmt.Sprintf("Expected HTTP error status code for %q but received %d", url+"?"+values.Encode(), code)) 85 | } 86 | 87 | return isErrorCode 88 | } 89 | 90 | // HTTPStatusCode asserts that a specified handler returns a specified status code. 91 | // 92 | // assert.HTTPStatusCode(t, myHandler, "GET", "/notImplemented", nil, 501) 93 | // 94 | // Returns whether the assertion was successful (true) or not (false). 95 | func HTTPStatusCode(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, statuscode int, msgAndArgs ...interface{}) bool { 96 | if h, ok := t.(tHelper); ok { 97 | h.Helper() 98 | } 99 | code, err := httpCode(handler, method, url, values) 100 | if err != nil { 101 | Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err)) 102 | } 103 | 104 | successful := code == statuscode 105 | if !successful { 106 | Fail(t, fmt.Sprintf("Expected HTTP status code %d for %q but received %d", statuscode, url+"?"+values.Encode(), code)) 107 | } 108 | 109 | return successful 110 | } 111 | 112 | // HTTPBody is a helper that returns HTTP body of the response. It returns 113 | // empty string if building a new request fails. 114 | func HTTPBody(handler http.HandlerFunc, method, url string, values url.Values) string { 115 | w := httptest.NewRecorder() 116 | req, err := http.NewRequest(method, url+"?"+values.Encode(), nil) 117 | if err != nil { 118 | return "" 119 | } 120 | handler(w, req) 121 | return w.Body.String() 122 | } 123 | 124 | // HTTPBodyContains asserts that a specified handler returns a 125 | // body that contains a string. 126 | // 127 | // assert.HTTPBodyContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") 128 | // 129 | // Returns whether the assertion was successful (true) or not (false). 130 | func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool { 131 | if h, ok := t.(tHelper); ok { 132 | h.Helper() 133 | } 134 | body := HTTPBody(handler, method, url, values) 135 | 136 | contains := strings.Contains(body, fmt.Sprint(str)) 137 | if !contains { 138 | Fail(t, fmt.Sprintf("Expected response body for \"%s\" to contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body)) 139 | } 140 | 141 | return contains 142 | } 143 | 144 | // HTTPBodyNotContains asserts that a specified handler returns a 145 | // body that does not contain a string. 146 | // 147 | // assert.HTTPBodyNotContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") 148 | // 149 | // Returns whether the assertion was successful (true) or not (false). 150 | func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool { 151 | if h, ok := t.(tHelper); ok { 152 | h.Helper() 153 | } 154 | body := HTTPBody(handler, method, url, values) 155 | 156 | contains := strings.Contains(body, fmt.Sprint(str)) 157 | if contains { 158 | Fail(t, fmt.Sprintf("Expected response body for \"%s\" to NOT contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body)) 159 | } 160 | 161 | return !contains 162 | } 163 | -------------------------------------------------------------------------------- /vendor/github.com/timtadh/data-structures/LICENSE: -------------------------------------------------------------------------------- 1 | The data-structures library 2 | 3 | Copyright (C) 2013-2017 Tim Henderson (tim.tadh@gmail.com) 4 | Case Western Reserve University, Cleveland, Ohio 5 | Google Inc. 6 | 7 | This program is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License along 18 | with this program; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 20 | 21 | 22 | 23 | Copyright (C) 2009 The Go Authors (for portions of rand/) 24 | This portion is used under the terms of the Go license: 25 | https://github.com/golang/go/blob/master/LICENSE 26 | (which is a BSD 3-clause license copied below) 27 | 28 | Redistribution and use in source and binary forms, with or without 29 | modification, are permitted provided that the following conditions 30 | are met: 31 | 32 | * Redistributions of source code must retain the above copyright 33 | notice, this list of conditions and the following disclaimer. 34 | * Redistributions in binary form must reproduce the above 35 | copyright notice, this list of conditions and the following 36 | disclaimer in the documentation and/or other materials provided with 37 | the distribution. 38 | * Neither the name of Google Inc. nor the names of its 39 | contributors may be used to endorse or promote products derived from 40 | this software without specific prior written permission. 41 | 42 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 43 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 44 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 45 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 46 | COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 47 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 48 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 49 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 50 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 51 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 52 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 53 | POSSIBILITY OF SUCH DAMAGE. 54 | -------------------------------------------------------------------------------- /vendor/github.com/timtadh/data-structures/errors/errors.go: -------------------------------------------------------------------------------- 1 | package errors 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "runtime" 7 | "strings" 8 | ) 9 | 10 | var SkipLogging map[string]bool 11 | 12 | func init() { 13 | SkipLogging = make(map[string]bool, 10) 14 | } 15 | 16 | type Error struct { 17 | Errs []error 18 | Stack []byte 19 | } 20 | 21 | func Errorf(format string, args ...interface{}) error { 22 | buf := make([]byte, 50000) 23 | n := runtime.Stack(buf, true) 24 | trace := make([]byte, n) 25 | copy(trace, buf) 26 | return &Error{ 27 | Errs: []error{fmt.Errorf(format, args...)}, 28 | Stack: trace, 29 | } 30 | } 31 | 32 | func Logf(level, format string, args ...interface{}) { 33 | if SkipLogging[level] { 34 | return 35 | } 36 | pc, _, line, ok := runtime.Caller(1) 37 | if !ok { 38 | log.Printf(format, args) 39 | return 40 | } 41 | fn := runtime.FuncForPC(pc) 42 | msg := fmt.Sprintf(format, args...) 43 | log.Printf("%v (%v:%v): %v", level, fn.Name(), line, msg) 44 | } 45 | 46 | func (e *Error) Chain(err error) error { 47 | e.Errs = append(e.Errs, err) 48 | return e 49 | } 50 | 51 | func (e *Error) Error() string { 52 | if e == nil { 53 | return "Error " 54 | } else if len(e.Errs) == 0 { 55 | return fmt.Sprintf("%v\n%s", e.Errs, string(e.Stack)) 56 | } else if len(e.Errs) == 1 { 57 | return fmt.Sprintf("%v\n%s", e.Errs[0], string(e.Stack)) 58 | } else { 59 | errs := make([]string, 0, len(e.Errs)) 60 | for _, err := range e.Errs { 61 | errs = append(errs, err.Error()) 62 | } 63 | return fmt.Sprintf("{%v}\n%s", strings.Join(errs, ", "), string(e.Stack)) 64 | } 65 | } 66 | 67 | func (e *Error) String() string { 68 | return e.Error() 69 | } 70 | 71 | type ErrorFmter func(a ...interface{}) error 72 | 73 | func NotFound(a ...interface{}) error { 74 | // return fmt.Errorf("Key '%v' was not found.", a...) 75 | return Errorf("Key was not found.") 76 | } 77 | 78 | func NotFoundInBucket(a ...interface{}) error { 79 | return Errorf("Key, '%v', was not in bucket when expected.", a...) 80 | } 81 | 82 | func InvalidKey(a ...interface{}) error { 83 | return Errorf("Key, '%v', is invalid, %s", a...) 84 | } 85 | 86 | func TSTError(a ...interface{}) error { 87 | return Errorf("Internal TST error - "+a[0].(string), a[1:]...) 88 | } 89 | 90 | func NegativeSize(a ...interface{}) error { 91 | return Errorf("Negative size") 92 | } 93 | 94 | func BpTreeError(a ...interface{}) error { 95 | return Errorf("Internal B+ Tree error - "+a[0].(string), a[1:]...) 96 | } 97 | 98 | var Errors map[string]ErrorFmter = map[string]ErrorFmter{ 99 | "not-found": NotFound, 100 | "not-found-in-bucket": NotFoundInBucket, 101 | "invalid-key": InvalidKey, 102 | "tst-error": TSTError, 103 | "negative-size": NegativeSize, 104 | "bptree-error": BpTreeError, 105 | } 106 | -------------------------------------------------------------------------------- /vendor/github.com/timtadh/data-structures/hashtable/hashtable.go: -------------------------------------------------------------------------------- 1 | package hashtable 2 | 3 | import . "github.com/timtadh/data-structures/types" 4 | import . "github.com/timtadh/data-structures/errors" 5 | 6 | type entry struct { 7 | key Hashable 8 | value interface{} 9 | next *entry 10 | } 11 | 12 | type Hash struct { 13 | table []*entry 14 | size int 15 | } 16 | 17 | func (self *entry) Put(key Hashable, value interface{}) (e *entry, appended bool) { 18 | if self == nil { 19 | return &entry{key, value, nil}, true 20 | } 21 | if self.key.Equals(key) { 22 | self.value = value 23 | return self, false 24 | } else { 25 | self.next, appended = self.next.Put(key, value) 26 | return self, appended 27 | } 28 | } 29 | 30 | func (self *entry) Get(key Hashable) (has bool, value interface{}) { 31 | if self == nil { 32 | return false, nil 33 | } else if self.key.Equals(key) { 34 | return true, self.value 35 | } else { 36 | return self.next.Get(key) 37 | } 38 | } 39 | 40 | func (self *entry) Remove(key Hashable) *entry { 41 | if self == nil { 42 | panic(Errors["not-found-in-bucket"](key)) 43 | } 44 | if self.key.Equals(key) { 45 | return self.next 46 | } else { 47 | self.next = self.next.Remove(key) 48 | return self 49 | } 50 | } 51 | 52 | func NewHashTable(initial_size int) *Hash { 53 | return &Hash{ 54 | table: make([]*entry, initial_size), 55 | size: 0, 56 | } 57 | } 58 | 59 | func (self *Hash) bucket(key Hashable) int { 60 | return key.Hash() % len(self.table) 61 | } 62 | 63 | func (self *Hash) Size() int { return self.size } 64 | 65 | func (self *Hash) Put(key Hashable, value interface{}) (err error) { 66 | bucket := self.bucket(key) 67 | var appended bool 68 | self.table[bucket], appended = self.table[bucket].Put(key, value) 69 | if appended { 70 | self.size += 1 71 | } 72 | if self.size*2 > len(self.table) { 73 | return self.expand() 74 | } 75 | return nil 76 | } 77 | 78 | func (self *Hash) expand() error { 79 | table := self.table 80 | self.table = make([]*entry, len(table)*2) 81 | self.size = 0 82 | for _, E := range table { 83 | for e := E; e != nil; e = e.next { 84 | if err := self.Put(e.key, e.value); err != nil { 85 | return err 86 | } 87 | } 88 | } 89 | return nil 90 | } 91 | 92 | func (self *Hash) Get(key Hashable) (value interface{}, err error) { 93 | bucket := self.bucket(key) 94 | if has, value := self.table[bucket].Get(key); has { 95 | return value, nil 96 | } else { 97 | return nil, Errors["not-found"](key) 98 | } 99 | } 100 | 101 | func (self *Hash) Has(key Hashable) (has bool) { 102 | has, _ = self.table[self.bucket(key)].Get(key) 103 | return 104 | } 105 | 106 | func (self *Hash) Remove(key Hashable) (value interface{}, err error) { 107 | bucket := self.bucket(key) 108 | has, value := self.table[bucket].Get(key) 109 | if !has { 110 | return nil, Errors["not-found"](key) 111 | } 112 | self.table[bucket] = self.table[bucket].Remove(key) 113 | self.size -= 1 114 | return value, nil 115 | } 116 | 117 | func (self *Hash) Iterate() KVIterator { 118 | table := self.table 119 | i := -1 120 | var e *entry 121 | var kv_iterator KVIterator 122 | kv_iterator = func() (key Hashable, val interface{}, next KVIterator) { 123 | for e == nil { 124 | i++ 125 | if i >= len(table) { 126 | return nil, nil, nil 127 | } 128 | e = table[i] 129 | } 130 | key = e.key 131 | val = e.value 132 | e = e.next 133 | return key, val, kv_iterator 134 | } 135 | return kv_iterator 136 | } 137 | 138 | func (self *Hash) Items() (vi KIterator) { 139 | return MakeItemsIterator(self) 140 | } 141 | 142 | func (self *Hash) Keys() KIterator { 143 | return MakeKeysIterator(self) 144 | } 145 | 146 | func (self *Hash) Values() Iterator { 147 | return MakeValuesIterator(self) 148 | } 149 | -------------------------------------------------------------------------------- /vendor/github.com/timtadh/data-structures/hashtable/linhash.go: -------------------------------------------------------------------------------- 1 | package hashtable 2 | 3 | import ( 4 | "github.com/timtadh/data-structures/tree/avl" 5 | . "github.com/timtadh/data-structures/types" 6 | ) 7 | 8 | const ( 9 | UTILIZATION = .75 10 | RECORDS_PER_BLOCK = 16 11 | ) 12 | 13 | type bst struct { 14 | hash int 15 | key Hashable 16 | value interface{} 17 | left *bst 18 | right *bst 19 | } 20 | 21 | type LinearHash struct { 22 | table []*avl.AvlNode 23 | n uint 24 | r uint 25 | i uint 26 | } 27 | 28 | func NewLinearHash() *LinearHash { 29 | N := uint(32) 30 | I := uint(5) 31 | return &LinearHash{ 32 | table: make([]*avl.AvlNode, N), 33 | n: N, 34 | r: 0, 35 | i: I, 36 | } 37 | } 38 | 39 | func (self *LinearHash) bucket(key Hashable) uint { 40 | m := uint(key.Hash() & ((1 << self.i) - 1)) 41 | if m < self.n { 42 | return m 43 | } else { 44 | return m ^ (1 << (self.i - 1)) 45 | } 46 | } 47 | 48 | func (self *LinearHash) Size() int { 49 | return int(self.r) 50 | } 51 | 52 | func (self *LinearHash) Put(key Hashable, value interface{}) (err error) { 53 | var updated bool 54 | bkt_idx := self.bucket(key) 55 | self.table[bkt_idx], updated = self.table[bkt_idx].Put(key, value) 56 | if !updated { 57 | self.r += 1 58 | } 59 | if float64(self.r) > UTILIZATION*float64(self.n)*float64(RECORDS_PER_BLOCK) { 60 | return self.split() 61 | } 62 | return nil 63 | } 64 | 65 | func (self *LinearHash) Get(key Hashable) (value interface{}, err error) { 66 | bkt_idx := self.bucket(key) 67 | return self.table[bkt_idx].Get(key) 68 | } 69 | 70 | func (self *LinearHash) Has(key Hashable) bool { 71 | bkt_idx := self.bucket(key) 72 | return self.table[bkt_idx].Has(key) 73 | } 74 | 75 | func (self *LinearHash) Remove(key Hashable) (value interface{}, err error) { 76 | bkt_idx := self.bucket(key) 77 | self.table[bkt_idx], value, err = self.table[bkt_idx].Remove(key) 78 | if err == nil { 79 | self.r -= 1 80 | } 81 | return 82 | } 83 | 84 | func (self *LinearHash) split() (err error) { 85 | bkt_idx := self.n % (1 << (self.i - 1)) 86 | old_bkt := self.table[bkt_idx] 87 | var bkt_a, bkt_b *avl.AvlNode 88 | self.n += 1 89 | if self.n > (1 << self.i) { 90 | self.i += 1 91 | } 92 | for key, value, next := old_bkt.Iterate()(); next != nil; key, value, next = next() { 93 | if self.bucket(key.(Hashable)) == bkt_idx { 94 | bkt_a, _ = bkt_a.Put(key.(Hashable), value) 95 | } else { 96 | bkt_b, _ = bkt_b.Put(key.(Hashable), value) 97 | } 98 | } 99 | self.table[bkt_idx] = bkt_a 100 | self.table = append(self.table, bkt_b) 101 | return nil 102 | } 103 | 104 | func (self *LinearHash) Iterate() KVIterator { 105 | table := self.table 106 | i := 0 107 | iter := table[i].Iterate() 108 | var kv_iterator KVIterator 109 | kv_iterator = func() (key Hashable, val interface{}, next KVIterator) { 110 | key, val, iter = iter() 111 | for iter == nil { 112 | i++ 113 | if i >= len(table) { 114 | return nil, nil, nil 115 | } 116 | key, val, iter = table[i].Iterate()() 117 | } 118 | return key, val, kv_iterator 119 | } 120 | return kv_iterator 121 | } 122 | 123 | func (self *LinearHash) Items() (vi KIterator) { 124 | return MakeItemsIterator(self) 125 | } 126 | 127 | func (self *LinearHash) Keys() KIterator { 128 | return MakeKeysIterator(self) 129 | } 130 | 131 | func (self *LinearHash) Values() Iterator { 132 | return MakeValuesIterator(self) 133 | } 134 | -------------------------------------------------------------------------------- /vendor/github.com/timtadh/data-structures/linked/linked.go: -------------------------------------------------------------------------------- 1 | package linked 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | import ( 9 | "github.com/timtadh/data-structures/errors" 10 | "github.com/timtadh/data-structures/list" 11 | "github.com/timtadh/data-structures/types" 12 | ) 13 | 14 | // A doubly linked list node. 15 | type Node struct { 16 | Data types.Hashable 17 | Next, Prev *Node 18 | } 19 | 20 | // Compares the Data of the node to the passed element. 21 | func (n *Node) Equals(b types.Equatable) bool { 22 | switch x := b.(type) { 23 | case *Node: 24 | return n.Data.Equals(x.Data) 25 | default: 26 | return n.Data.Equals(b) 27 | } 28 | } 29 | 30 | // Compares the Data of the node to the passed element. 31 | func (n *Node) Less(b types.Sortable) bool { 32 | switch x := b.(type) { 33 | case *Node: 34 | return n.Data.Less(x.Data) 35 | default: 36 | return n.Data.Less(b) 37 | } 38 | } 39 | 40 | // Hashes the Data of the node to the passed element. 41 | func (n *Node) Hash() int { 42 | return n.Data.Hash() 43 | } 44 | 45 | // A doubly linked list. There is no synchronization. 46 | // The fields are publically accessible to allow for easy customization. 47 | type LinkedList struct { 48 | Length int 49 | Head *Node 50 | Tail *Node 51 | } 52 | 53 | func New() *LinkedList { 54 | return &LinkedList{ 55 | Length: 0, 56 | Head: nil, 57 | Tail: nil, 58 | } 59 | } 60 | 61 | func (l *LinkedList) Size() int { 62 | return l.Length 63 | } 64 | 65 | func (l *LinkedList) Items() (it types.KIterator) { 66 | cur := l.Head 67 | it = func() (item types.Hashable, _ types.KIterator) { 68 | if cur == nil { 69 | return nil, nil 70 | } 71 | item = cur.Data 72 | cur = cur.Next 73 | return item, it 74 | } 75 | return it 76 | } 77 | 78 | func (l *LinkedList) Backwards() (it types.KIterator) { 79 | cur := l.Tail 80 | it = func() (item types.Hashable, _ types.KIterator) { 81 | if cur == nil { 82 | return nil, nil 83 | } 84 | item = cur.Data 85 | cur = cur.Prev 86 | return item, it 87 | } 88 | return it 89 | } 90 | 91 | func (l *LinkedList) Has(item types.Hashable) bool { 92 | for x, next := l.Items()(); next != nil; x, next = next() { 93 | if x.Equals(item) { 94 | return true 95 | } 96 | } 97 | return false 98 | } 99 | 100 | func (l *LinkedList) Push(item types.Hashable) (err error) { 101 | return l.EnqueBack(item) 102 | } 103 | 104 | func (l *LinkedList) Pop() (item types.Hashable, err error) { 105 | return l.DequeBack() 106 | } 107 | 108 | func (l *LinkedList) EnqueFront(item types.Hashable) (err error) { 109 | n := &Node{Data: item, Next: l.Head} 110 | if l.Head != nil { 111 | l.Head.Prev = n 112 | } else { 113 | l.Tail = n 114 | } 115 | l.Head = n 116 | l.Length++ 117 | return nil 118 | } 119 | 120 | func (l *LinkedList) EnqueBack(item types.Hashable) (err error) { 121 | n := &Node{Data: item, Prev: l.Tail} 122 | if l.Tail != nil { 123 | l.Tail.Next = n 124 | } else { 125 | l.Head = n 126 | } 127 | l.Tail = n 128 | l.Length++ 129 | return nil 130 | } 131 | 132 | func (l *LinkedList) DequeFront() (item types.Hashable, err error) { 133 | if l.Head == nil { 134 | return nil, errors.Errorf("List is empty") 135 | } 136 | item = l.Head.Data 137 | l.Head = l.Head.Next 138 | if l.Head != nil { 139 | l.Head.Prev = nil 140 | } else { 141 | l.Tail = nil 142 | } 143 | l.Length-- 144 | return item, nil 145 | } 146 | 147 | func (l *LinkedList) DequeBack() (item types.Hashable, err error) { 148 | if l.Tail == nil { 149 | return nil, errors.Errorf("List is empty") 150 | } 151 | item = l.Tail.Data 152 | l.Tail = l.Tail.Prev 153 | if l.Tail != nil { 154 | l.Tail.Next = nil 155 | } else { 156 | l.Head = nil 157 | } 158 | l.Length-- 159 | return item, nil 160 | } 161 | 162 | func (l *LinkedList) First() (item types.Hashable) { 163 | if l.Head == nil { 164 | return nil 165 | } 166 | return l.Head.Data 167 | } 168 | 169 | func (l *LinkedList) Last() (item types.Hashable) { 170 | if l.Tail == nil { 171 | return nil 172 | } 173 | return l.Tail.Data 174 | } 175 | 176 | // Can be compared to any types.IterableContainer 177 | func (l *LinkedList) Equals(b types.Equatable) bool { 178 | if o, ok := b.(types.IterableContainer); ok { 179 | return list.Equals(l, o) 180 | } else { 181 | return false 182 | } 183 | } 184 | 185 | // Can be compared to any types.IterableContainer 186 | func (l *LinkedList) Less(b types.Sortable) bool { 187 | if o, ok := b.(types.IterableContainer); ok { 188 | return list.Less(l, o) 189 | } else { 190 | return false 191 | } 192 | } 193 | 194 | func (l *LinkedList) Hash() int { 195 | return list.Hash(l) 196 | } 197 | 198 | func (l *LinkedList) String() string { 199 | if l.Length <= 0 { 200 | return "{}" 201 | } 202 | items := make([]string, 0, l.Length) 203 | for item, next := l.Items()(); next != nil; item, next = next() { 204 | items = append(items, fmt.Sprintf("%v", item)) 205 | } 206 | return "{" + strings.Join(items, ", ") + "}" 207 | } 208 | -------------------------------------------------------------------------------- /vendor/github.com/timtadh/data-structures/linked/unique.go: -------------------------------------------------------------------------------- 1 | package linked 2 | 3 | import ( 4 | "github.com/timtadh/data-structures/hashtable" 5 | "github.com/timtadh/data-structures/list" 6 | "github.com/timtadh/data-structures/set" 7 | "github.com/timtadh/data-structures/types" 8 | ) 9 | 10 | type UniqueDeque struct { 11 | queue *LinkedList 12 | set types.Set 13 | } 14 | 15 | // A double ended queue that only allows unique items inside. Constructed from a 16 | // doubly linked list and a linear hash table. 17 | func NewUniqueDeque() *UniqueDeque { 18 | return &UniqueDeque{ 19 | queue: New(), 20 | set: set.NewSetMap(hashtable.NewLinearHash()), 21 | } 22 | } 23 | 24 | func (l *UniqueDeque) Size() int { 25 | return l.queue.Size() 26 | } 27 | 28 | func (l *UniqueDeque) Items() (it types.KIterator) { 29 | return l.queue.Items() 30 | } 31 | 32 | func (l *UniqueDeque) Backwards() (it types.KIterator) { 33 | return l.queue.Backwards() 34 | } 35 | 36 | func (l *UniqueDeque) Has(item types.Hashable) bool { 37 | return l.set.Has(item) 38 | } 39 | 40 | func (l *UniqueDeque) Push(item types.Hashable) (err error) { 41 | return l.EnqueBack(item) 42 | } 43 | 44 | func (l *UniqueDeque) Pop() (item types.Hashable, err error) { 45 | return l.DequeBack() 46 | } 47 | 48 | func (l *UniqueDeque) EnqueFront(item types.Hashable) (err error) { 49 | if l.Has(item) { 50 | return nil 51 | } 52 | err = l.queue.EnqueFront(item) 53 | if err != nil { 54 | return err 55 | } 56 | return l.set.Add(item) 57 | } 58 | 59 | func (l *UniqueDeque) EnqueBack(item types.Hashable) (err error) { 60 | if l.Has(item) { 61 | return nil 62 | } 63 | err = l.queue.EnqueBack(item) 64 | if err != nil { 65 | return err 66 | } 67 | return l.set.Add(item) 68 | } 69 | 70 | func (l *UniqueDeque) DequeFront() (item types.Hashable, err error) { 71 | item, err = l.queue.DequeFront() 72 | if err != nil { 73 | return nil, err 74 | } 75 | err = l.set.Delete(item) 76 | if err != nil { 77 | return nil, err 78 | } 79 | return item, nil 80 | } 81 | 82 | func (l *UniqueDeque) DequeBack() (item types.Hashable, err error) { 83 | item, err = l.queue.DequeBack() 84 | if err != nil { 85 | return nil, err 86 | } 87 | err = l.set.Delete(item) 88 | if err != nil { 89 | return nil, err 90 | } 91 | return item, nil 92 | } 93 | 94 | func (l *UniqueDeque) First() (item types.Hashable) { 95 | return l.queue.First() 96 | } 97 | 98 | func (l *UniqueDeque) Last() (item types.Hashable) { 99 | return l.queue.Last() 100 | } 101 | 102 | // Can be compared to any types.IterableContainer 103 | func (l *UniqueDeque) Equals(b types.Equatable) bool { 104 | return l.queue.Equals(b) 105 | } 106 | 107 | // Can be compared to any types.IterableContainer 108 | func (l *UniqueDeque) Less(b types.Sortable) bool { 109 | return l.queue.Less(b) 110 | } 111 | 112 | func (l *UniqueDeque) Hash() int { 113 | return list.Hash(l.queue) 114 | } 115 | 116 | func (l *UniqueDeque) String() string { 117 | return l.queue.String() 118 | } 119 | -------------------------------------------------------------------------------- /vendor/github.com/timtadh/data-structures/list/sorted.go: -------------------------------------------------------------------------------- 1 | package list 2 | 3 | import ( 4 | "bytes" 5 | "log" 6 | ) 7 | 8 | import ( 9 | "github.com/timtadh/data-structures/errors" 10 | "github.com/timtadh/data-structures/types" 11 | ) 12 | 13 | type MSorted struct { 14 | MList 15 | AllowDups bool 16 | } 17 | 18 | func NewMSorted(s *Sorted, marshal types.ItemMarshal, unmarshal types.ItemUnmarshal) *MSorted { 19 | return &MSorted{ 20 | MList: *NewMList(&s.list, marshal, unmarshal), 21 | AllowDups: s.allowDups, 22 | } 23 | } 24 | 25 | func (m *MSorted) Sorted() *Sorted { 26 | return &Sorted{m.MList.List, m.AllowDups} 27 | } 28 | 29 | func (m *MSorted) MarshalBinary() ([]byte, error) { 30 | var allowDups byte 31 | if m.AllowDups { 32 | allowDups = 1 33 | } else { 34 | allowDups = 0 35 | } 36 | b, err := m.MList.MarshalBinary() 37 | if err != nil { 38 | return nil, err 39 | } 40 | return bytes.Join([][]byte{[]byte{allowDups}, b}, []byte{}), nil 41 | } 42 | 43 | func (m *MSorted) UnmarshalBinary(bytes []byte) error { 44 | allowDups := bytes[0] 45 | if allowDups == 0 { 46 | m.AllowDups = false 47 | } else { 48 | m.AllowDups = true 49 | } 50 | return m.MList.UnmarshalBinary(bytes[1:]) 51 | } 52 | 53 | type Sorted struct { 54 | list List 55 | allowDups bool 56 | } 57 | 58 | // Creates a sorted list. 59 | func NewSorted(initialSize int, allowDups bool) *Sorted { 60 | return &Sorted{ 61 | list: *New(initialSize), 62 | allowDups: allowDups, 63 | } 64 | } 65 | 66 | // Creates a fixed size sorted list. 67 | func NewFixedSorted(size int, allowDups bool) *Sorted { 68 | return &Sorted{ 69 | list: *Fixed(size), 70 | allowDups: allowDups, 71 | } 72 | } 73 | 74 | func SortedFromSlice(items []types.Hashable, allowDups bool) *Sorted { 75 | s := NewSorted(len(items), allowDups) 76 | for _, item := range items { 77 | err := s.Add(item) 78 | if err != nil { 79 | log.Panic(err) 80 | } 81 | } 82 | return s 83 | } 84 | 85 | func (s *Sorted) Clear() { 86 | s.list.Clear() 87 | } 88 | 89 | func (s *Sorted) Size() int { 90 | return s.list.Size() 91 | } 92 | 93 | func (s *Sorted) Full() bool { 94 | return s.list.Full() 95 | } 96 | 97 | func (s *Sorted) Empty() bool { 98 | return s.list.Empty() 99 | } 100 | 101 | func (s *Sorted) Copy() *Sorted { 102 | return &Sorted{*s.list.Copy(), s.allowDups} 103 | } 104 | 105 | func (s *Sorted) Has(item types.Hashable) (has bool) { 106 | _, has, err := s.Find(item) 107 | if err != nil { 108 | log.Println(err) 109 | return false 110 | } 111 | return has 112 | } 113 | 114 | func (s *Sorted) Extend(other types.KIterator) (err error) { 115 | for item, next := other(); next != nil; item, next = next() { 116 | err := s.Add(item) 117 | if err != nil { 118 | return err 119 | } 120 | } 121 | return nil 122 | } 123 | 124 | func (s *Sorted) Item(item types.Hashable) (types.Hashable, error) { 125 | i, has, err := s.Find(item) 126 | if err != nil { 127 | return nil, err 128 | } else if !has { 129 | return nil, errors.Errorf("Item not found %v", item) 130 | } 131 | return s.Get(i) 132 | } 133 | 134 | func (s *Sorted) Get(i int) (item types.Hashable, err error) { 135 | return s.list.Get(i) 136 | } 137 | 138 | func (s *Sorted) Remove(i int) (err error) { 139 | return s.list.Remove(i) 140 | } 141 | 142 | func (s *Sorted) Add(item types.Hashable) (err error) { 143 | i, has, err := s.Find(item) 144 | if err != nil { 145 | return err 146 | } else if s.allowDups { 147 | return s.list.Insert(i, item) 148 | } else if !has { 149 | return s.list.Insert(i, item) 150 | } 151 | return nil 152 | } 153 | 154 | func (s *Sorted) Delete(item types.Hashable) (err error) { 155 | i, has, err := s.Find(item) 156 | if err != nil { 157 | return err 158 | } else if !has { 159 | return errors.Errorf("item %v not in the table", item) 160 | } 161 | return s.list.Remove(i) 162 | return nil 163 | } 164 | 165 | func (s *Sorted) Equals(b types.Equatable) bool { 166 | return s.list.Equals(b) 167 | } 168 | 169 | func (s *Sorted) Less(b types.Sortable) bool { 170 | return s.list.Less(b) 171 | } 172 | 173 | func (s *Sorted) Hash() int { 174 | return s.list.Hash() 175 | } 176 | 177 | func (s *Sorted) Items() (it types.KIterator) { 178 | return s.list.Items() 179 | } 180 | 181 | func (s *Sorted) ItemsInReverse() (it types.KIterator) { 182 | return s.list.ItemsInReverse() 183 | } 184 | 185 | func (s *Sorted) String() string { 186 | return s.list.String() 187 | } 188 | 189 | func (s *Sorted) Find(item types.Hashable) (int, bool, error) { 190 | var l int = 0 191 | var r int = s.Size() - 1 192 | var m int 193 | for l <= r { 194 | m = ((r - l) >> 1) + l 195 | im, err := s.list.Get(m) 196 | if err != nil { 197 | return -1, false, err 198 | } 199 | if item.Less(im) { 200 | r = m - 1 201 | } else if item.Equals(im) { 202 | for j := m; j > 0; j-- { 203 | ij_1, err := s.list.Get(j - 1) 204 | if err != nil { 205 | return -1, false, err 206 | } 207 | if !item.Equals(ij_1) { 208 | return j, true, nil 209 | } 210 | } 211 | return 0, true, nil 212 | } else { 213 | l = m + 1 214 | } 215 | } 216 | return l, false, nil 217 | } 218 | -------------------------------------------------------------------------------- /vendor/github.com/timtadh/data-structures/rand/rand.go: -------------------------------------------------------------------------------- 1 | package rand 2 | 3 | import ( 4 | "math/rand" 5 | "sync" 6 | ) 7 | 8 | // ThreadSafeRand provides a thread safe version of math/rand.Rand using 9 | // the same technique used in the math/rand package to make the top level 10 | // functions thread safe. 11 | func ThreadSafeRand(seed int64) *rand.Rand { 12 | return rand.New(&lockedSource{src: rand.NewSource(seed).(rand.Source64)}) 13 | } 14 | 15 | // from: https://golang.org/src/math/rand/rand.go?s=8161:8175#L317 16 | type lockedSource struct { 17 | lk sync.Mutex 18 | src rand.Source64 19 | } 20 | 21 | func (r *lockedSource) Int63() (n int64) { 22 | r.lk.Lock() 23 | n = r.src.Int63() 24 | r.lk.Unlock() 25 | return 26 | } 27 | 28 | func (r *lockedSource) Uint64() (n uint64) { 29 | r.lk.Lock() 30 | n = r.src.Uint64() 31 | r.lk.Unlock() 32 | return 33 | } 34 | 35 | func (r *lockedSource) Seed(seed int64) { 36 | r.lk.Lock() 37 | r.src.Seed(seed) 38 | r.lk.Unlock() 39 | } 40 | 41 | // seedPos implements Seed for a lockedSource without a race condiiton. 42 | func (r *lockedSource) seedPos(seed int64, readPos *int8) { 43 | r.lk.Lock() 44 | r.src.Seed(seed) 45 | *readPos = 0 46 | r.lk.Unlock() 47 | } 48 | 49 | // read implements Read for a lockedSource without a race condition. 50 | func (r *lockedSource) read(p []byte, readVal *int64, readPos *int8) (n int, err error) { 51 | r.lk.Lock() 52 | n, err = read(p, r.src.Int63, readVal, readPos) 53 | r.lk.Unlock() 54 | return 55 | } 56 | 57 | func read(p []byte, int63 func() int64, readVal *int64, readPos *int8) (n int, err error) { 58 | pos := *readPos 59 | val := *readVal 60 | for n = 0; n < len(p); n++ { 61 | if pos == 0 { 62 | val = int63() 63 | pos = 7 64 | } 65 | p[n] = byte(val) 66 | val >>= 8 67 | pos-- 68 | } 69 | *readPos = pos 70 | *readVal = val 71 | return 72 | } 73 | -------------------------------------------------------------------------------- /vendor/github.com/timtadh/data-structures/set/mapset.go: -------------------------------------------------------------------------------- 1 | package set 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | import ( 8 | "github.com/timtadh/data-structures/errors" 9 | "github.com/timtadh/data-structures/types" 10 | ) 11 | 12 | type MapSet struct { 13 | Set types.Set 14 | } 15 | 16 | func mapEntry(item types.Hashable) (*types.MapEntry, error) { 17 | if me, ok := item.(*types.MapEntry); ok { 18 | return me, nil 19 | } else { 20 | return nil, errors.Errorf("Must pass a *types.MapEntry, got %T", item) 21 | } 22 | } 23 | 24 | func asMapEntry(item types.Hashable) *types.MapEntry { 25 | if me, ok := item.(*types.MapEntry); ok { 26 | return me 27 | } else { 28 | return &types.MapEntry{item, nil} 29 | } 30 | } 31 | 32 | func NewMapSet(set types.Set) *MapSet { 33 | return &MapSet{set} 34 | } 35 | 36 | func (m *MapSet) Equals(b types.Equatable) bool { 37 | if o, ok := b.(*MapSet); ok { 38 | return m.Set.Equals(o.Set) 39 | } else { 40 | return false 41 | } 42 | } 43 | 44 | func (m *MapSet) Size() int { 45 | return m.Set.Size() 46 | } 47 | 48 | func (m *MapSet) Keys() types.KIterator { 49 | return types.MakeKeysIterator(m) 50 | } 51 | 52 | func (m *MapSet) Values() types.Iterator { 53 | return types.MakeValuesIterator(m) 54 | } 55 | 56 | func (m *MapSet) Iterate() (kvit types.KVIterator) { 57 | items := m.Items() 58 | kvit = func() (key types.Hashable, value interface{}, _ types.KVIterator) { 59 | var item types.Hashable 60 | item, items = items() 61 | if items == nil { 62 | return nil, nil, nil 63 | } 64 | me := item.(*types.MapEntry) 65 | return me.Key, me.Value, kvit 66 | } 67 | return kvit 68 | } 69 | 70 | func (m *MapSet) Items() types.KIterator { 71 | return m.Set.Items() 72 | } 73 | 74 | func (m *MapSet) Has(key types.Hashable) bool { 75 | return m.Set.Has(asMapEntry(key)) 76 | } 77 | 78 | func (m *MapSet) Add(item types.Hashable) (err error) { 79 | me, err := mapEntry(item) 80 | if err != nil { 81 | return err 82 | } 83 | return m.Set.Add(me) 84 | } 85 | 86 | func (m *MapSet) Put(key types.Hashable, value interface{}) (err error) { 87 | return m.Add(&types.MapEntry{key, value}) 88 | } 89 | 90 | func (m *MapSet) Get(key types.Hashable) (value interface{}, err error) { 91 | item, err := m.Set.Item(asMapEntry(key)) 92 | if err != nil { 93 | return nil, err 94 | } 95 | me, err := mapEntry(item) 96 | if err != nil { 97 | return nil, err 98 | } 99 | return me.Value, nil 100 | } 101 | 102 | func (m *MapSet) Item(key types.Hashable) (me types.Hashable, err error) { 103 | item, err := m.Set.Item(asMapEntry(key)) 104 | if err != nil { 105 | return nil, err 106 | } 107 | me, err = mapEntry(item) 108 | if err != nil { 109 | return nil, err 110 | } 111 | return me, nil 112 | } 113 | 114 | func (m *MapSet) Remove(key types.Hashable) (value interface{}, err error) { 115 | item, err := m.Get(asMapEntry(key)) 116 | if err != nil { 117 | return nil, err 118 | } 119 | err = m.Delete(key) 120 | if err != nil { 121 | return nil, err 122 | } 123 | return item, nil 124 | } 125 | 126 | func (m *MapSet) Delete(item types.Hashable) (err error) { 127 | return m.Set.Delete(asMapEntry(item)) 128 | } 129 | 130 | func (m *MapSet) Extend(items types.KIterator) (err error) { 131 | for item, items := items(); items != nil; item, items = items() { 132 | err := m.Add(item) 133 | if err != nil { 134 | return err 135 | } 136 | } 137 | return nil 138 | } 139 | 140 | func (m *MapSet) Union(b types.Set) (types.Set, error) { 141 | return Union(m, b) 142 | } 143 | 144 | func (m *MapSet) Intersect(b types.Set) (types.Set, error) { 145 | return Intersect(m, b) 146 | } 147 | 148 | func (m *MapSet) Subtract(b types.Set) (types.Set, error) { 149 | return Subtract(m, b) 150 | } 151 | 152 | func (m *MapSet) Subset(b types.Set) bool { 153 | return Subset(m, b) 154 | } 155 | 156 | func (m *MapSet) Superset(b types.Set) bool { 157 | return Superset(m, b) 158 | } 159 | 160 | func (m *MapSet) ProperSubset(b types.Set) bool { 161 | return ProperSubset(m, b) 162 | } 163 | 164 | func (m *MapSet) ProperSuperset(b types.Set) bool { 165 | return ProperSuperset(m, b) 166 | } 167 | 168 | func (m *MapSet) String() string { 169 | return fmt.Sprintf("%v", m.Set) 170 | } 171 | -------------------------------------------------------------------------------- /vendor/github.com/timtadh/data-structures/set/ops.go: -------------------------------------------------------------------------------- 1 | package set 2 | 3 | import ( 4 | "github.com/timtadh/data-structures/hashtable" 5 | "github.com/timtadh/data-structures/types" 6 | ) 7 | 8 | func newSetBestType(a types.Set, sizeHint int) types.Set { 9 | switch a.(type) { 10 | case *MapSet: 11 | return NewMapSet(NewSortedSet(sizeHint)) 12 | case *SortedSet: 13 | return NewSortedSet(sizeHint) 14 | case *SetMap: 15 | return NewSetMap(hashtable.NewLinearHash()) 16 | default: 17 | return NewSortedSet(sizeHint) 18 | } 19 | } 20 | 21 | func Union(a, b types.Set) (types.Set, error) { 22 | c := newSetBestType(a, a.Size()+b.Size()) 23 | err := c.Extend(a.Items()) 24 | if err != nil { 25 | return nil, err 26 | } 27 | err = c.Extend(b.Items()) 28 | if err != nil { 29 | return nil, err 30 | } 31 | return c, nil 32 | } 33 | 34 | func Intersect(a, b types.Set) (types.Set, error) { 35 | c := newSetBestType(a, a.Size()+b.Size()) 36 | for item, next := a.Items()(); next != nil; item, next = next() { 37 | if b.Has(item) { 38 | err := c.Add(item) 39 | if err != nil { 40 | return nil, err 41 | } 42 | } 43 | } 44 | return c, nil 45 | } 46 | 47 | // Unions s with o and returns a new Sorted Set 48 | func Subtract(a, b types.Set) (types.Set, error) { 49 | c := newSetBestType(a, a.Size()+b.Size()) 50 | for item, next := a.Items()(); next != nil; item, next = next() { 51 | if !b.Has(item) { 52 | err := c.Add(item) 53 | if err != nil { 54 | return nil, err 55 | } 56 | } 57 | } 58 | return c, nil 59 | } 60 | 61 | func Subset(a, b types.Set) bool { 62 | if a.Size() > b.Size() { 63 | return false 64 | } 65 | for item, next := a.Items()(); next != nil; item, next = next() { 66 | if !b.Has(item) { 67 | return false 68 | } 69 | } 70 | return true 71 | } 72 | 73 | func ProperSubset(a, b types.Set) bool { 74 | if a.Size() >= b.Size() { 75 | return false 76 | } 77 | return Subset(a, b) 78 | } 79 | 80 | func Superset(a, b types.Set) bool { 81 | return Subset(b, a) 82 | } 83 | 84 | func ProperSuperset(a, b types.Set) bool { 85 | return ProperSubset(b, a) 86 | } 87 | -------------------------------------------------------------------------------- /vendor/github.com/timtadh/data-structures/set/setmap.go: -------------------------------------------------------------------------------- 1 | package set 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | "github.com/timtadh/data-structures/errors" 8 | "github.com/timtadh/data-structures/types" 9 | ) 10 | 11 | type SetMap struct { 12 | types.Map 13 | } 14 | 15 | func NewSetMap(m types.Map) *SetMap { 16 | return &SetMap{m} 17 | } 18 | 19 | func (s *SetMap) String() string { 20 | if s.Size() <= 0 { 21 | return "{}" 22 | } 23 | items := make([]string, 0, s.Size()) 24 | for item, next := s.Items()(); next != nil; item, next = next() { 25 | items = append(items, fmt.Sprintf("%v", item)) 26 | } 27 | return "{" + strings.Join(items, ", ") + "}" 28 | } 29 | 30 | func (s *SetMap) Items() types.KIterator { 31 | return s.Keys() 32 | } 33 | 34 | // unimplemented 35 | func (s *SetMap) Item(item types.Hashable) (types.Hashable, error) { 36 | return nil, errors.Errorf("un-implemented") 37 | } 38 | 39 | // unimplemented 40 | func (s *SetMap) Equals(o types.Equatable) bool { 41 | panic(errors.Errorf("un-implemented")) 42 | } 43 | 44 | func (s *SetMap) Add(item types.Hashable) (err error) { 45 | return s.Put(item, nil) 46 | } 47 | 48 | func (s *SetMap) Delete(item types.Hashable) (err error) { 49 | _, err = s.Remove(item) 50 | return err 51 | } 52 | 53 | func (s *SetMap) Extend(items types.KIterator) (err error) { 54 | for item, next := items(); next != nil; item, next = next() { 55 | err := s.Add(item) 56 | if err != nil { 57 | return err 58 | } 59 | } 60 | return nil 61 | } 62 | 63 | // Unions s with o and returns a new SetMap (with a LinearHash) 64 | func (s *SetMap) Union(other types.Set) (types.Set, error) { 65 | return Union(s, other) 66 | } 67 | 68 | // Unions s with o and returns a new SetMap (with a LinearHash) 69 | func (s *SetMap) Intersect(other types.Set) (types.Set, error) { 70 | return Intersect(s, other) 71 | } 72 | 73 | // Unions s with o and returns a new SetMap (with a LinearHash) 74 | func (s *SetMap) Subtract(other types.Set) (types.Set, error) { 75 | return Subtract(s, other) 76 | } 77 | 78 | // Is s a subset of o? 79 | func (s *SetMap) Subset(o types.Set) bool { 80 | return Subset(s, o) 81 | } 82 | 83 | // Is s a proper subset of o? 84 | func (s *SetMap) ProperSubset(o types.Set) bool { 85 | return ProperSubset(s, o) 86 | } 87 | 88 | // Is s a superset of o? 89 | func (s *SetMap) Superset(o types.Set) bool { 90 | return Superset(s, o) 91 | } 92 | 93 | // Is s a proper superset of o? 94 | func (s *SetMap) ProperSuperset(o types.Set) bool { 95 | return ProperSuperset(s, o) 96 | } 97 | -------------------------------------------------------------------------------- /vendor/github.com/timtadh/data-structures/set/sortedset.go: -------------------------------------------------------------------------------- 1 | package set 2 | 3 | import ( 4 | crand "crypto/rand" 5 | "encoding/binary" 6 | "log" 7 | mrand "math/rand" 8 | ) 9 | 10 | import ( 11 | "github.com/timtadh/data-structures/errors" 12 | "github.com/timtadh/data-structures/list" 13 | trand "github.com/timtadh/data-structures/rand" 14 | "github.com/timtadh/data-structures/types" 15 | ) 16 | 17 | var rand *mrand.Rand 18 | 19 | func init() { 20 | seed := make([]byte, 8) 21 | if _, err := crand.Read(seed); err == nil { 22 | rand = trand.ThreadSafeRand(int64(binary.BigEndian.Uint64(seed))) 23 | } else { 24 | panic(err) 25 | } 26 | } 27 | 28 | type MSortedSet struct { 29 | list.MSorted 30 | } 31 | 32 | func NewMSortedSet(s *SortedSet, marshal types.ItemMarshal, unmarshal types.ItemUnmarshal) *MSortedSet { 33 | return &MSortedSet{ 34 | MSorted: *list.NewMSorted(&s.Sorted, marshal, unmarshal), 35 | } 36 | } 37 | 38 | func (m *MSortedSet) SortedSet() *SortedSet { 39 | return &SortedSet{*m.MSorted.Sorted()} 40 | } 41 | 42 | // SortedSet is a list.Sorted and therefore has all of the methods 43 | // that list.Sorted has. So although they do not show up in the generated 44 | // docs you can just do this: 45 | // 46 | // s := NewSortedSet(10) 47 | // s.Add(types.Int(5)) 48 | // s2 = s.Union(FromSlice([]types.Hashable{types.Int(7)})) 49 | // fmt.Println(s2.Has(types.Int(7))) 50 | // fmt.Println(s.Has(types.Int(7))) 51 | // 52 | type SortedSet struct { 53 | list.Sorted 54 | } 55 | 56 | func NewSortedSet(initialSize int) *SortedSet { 57 | return &SortedSet{*list.NewSorted(initialSize, false)} 58 | } 59 | 60 | func FromSlice(items []types.Hashable) *SortedSet { 61 | s := NewSortedSet(len(items)) 62 | for _, item := range items { 63 | err := s.Add(item) 64 | if err != nil { 65 | log.Panic(err) 66 | } 67 | } 68 | return s 69 | } 70 | 71 | func SortedFromSet(s types.Set) *SortedSet { 72 | if s == nil || s.Size() == 0 { 73 | return NewSortedSet(0) 74 | } 75 | n := NewSortedSet(s.Size()) 76 | for i, next := s.Items()(); next != nil; i, next = next() { 77 | n.Add(i) 78 | } 79 | return n 80 | } 81 | 82 | func (s *SortedSet) Copy() *SortedSet { 83 | return &SortedSet{*s.Sorted.Copy()} 84 | } 85 | 86 | func (s *SortedSet) Random() (item types.Hashable, err error) { 87 | if s.Size() <= 0 { 88 | return nil, errors.Errorf("Set is empty") 89 | } else if s.Size() <= 1 { 90 | return s.Get(0) 91 | } 92 | i := rand.Intn(s.Size()) 93 | return s.Get(i) 94 | } 95 | 96 | // Unions s with o and returns a new Sorted Set 97 | func (s *SortedSet) Union(other types.Set) (types.Set, error) { 98 | if o, ok := other.(*SortedSet); ok { 99 | return s.union(o) 100 | } else { 101 | return Union(s, other) 102 | } 103 | } 104 | 105 | func (s *SortedSet) union(o *SortedSet) (n *SortedSet, err error) { 106 | n = NewSortedSet(s.Size() + o.Size() + 10) 107 | cs, si := s.Items()() 108 | co, oi := o.Items()() 109 | for si != nil || oi != nil { 110 | var err error 111 | if si == nil { 112 | err = n.Add(co) 113 | co, oi = oi() 114 | } else if oi == nil { 115 | err = n.Add(cs) 116 | cs, si = si() 117 | } else if cs.Less(co) { 118 | err = n.Add(cs) 119 | cs, si = si() 120 | } else { 121 | err = n.Add(co) 122 | co, oi = oi() 123 | } 124 | if err != nil { 125 | return nil, err 126 | } 127 | } 128 | return n, nil 129 | } 130 | 131 | // Unions s with o and returns a new Sorted Set 132 | func (s *SortedSet) Intersect(other types.Set) (types.Set, error) { 133 | return Intersect(s, other) 134 | } 135 | 136 | // Unions s with o and returns a new Sorted Set 137 | func (s *SortedSet) Subtract(other types.Set) (types.Set, error) { 138 | return Subtract(s, other) 139 | } 140 | 141 | // Are there any overlapping elements? 142 | func (s *SortedSet) Overlap(o *SortedSet) bool { 143 | cs, si := s.Items()() 144 | co, oi := o.Items()() 145 | for si != nil && oi != nil { 146 | s := cs.(types.Hashable) 147 | o := co.(types.Hashable) 148 | if s.Equals(o) { 149 | return true 150 | } else if s.Less(o) { 151 | cs, si = si() 152 | } else { 153 | co, oi = oi() 154 | } 155 | } 156 | return false 157 | } 158 | 159 | // Is s a subset of o? 160 | func (s *SortedSet) Subset(o types.Set) bool { 161 | return Subset(s, o) 162 | } 163 | 164 | // Is s a proper subset of o? 165 | func (s *SortedSet) ProperSubset(o types.Set) bool { 166 | return ProperSubset(s, o) 167 | } 168 | 169 | // Is s a superset of o? 170 | func (s *SortedSet) Superset(o types.Set) bool { 171 | return Superset(s, o) 172 | } 173 | 174 | // Is s a proper superset of o? 175 | func (s *SortedSet) ProperSuperset(o types.Set) bool { 176 | return ProperSuperset(s, o) 177 | } 178 | -------------------------------------------------------------------------------- /vendor/github.com/timtadh/data-structures/tree/avl/avltree.go: -------------------------------------------------------------------------------- 1 | package avl 2 | 3 | import ( 4 | "github.com/timtadh/data-structures/errors" 5 | "github.com/timtadh/data-structures/tree" 6 | "github.com/timtadh/data-structures/types" 7 | ) 8 | 9 | func abs(i int) int { 10 | if i < 0 { 11 | return -i 12 | } 13 | return i 14 | } 15 | 16 | func max(a, b int) int { 17 | if a > b { 18 | return a 19 | } 20 | return b 21 | } 22 | 23 | type AvlTree struct { 24 | root *AvlNode 25 | } 26 | 27 | func NewAvlTree() *AvlTree { 28 | return &AvlTree{} 29 | } 30 | 31 | func (self *AvlTree) Root() types.TreeNode { 32 | return self.root 33 | } 34 | 35 | func (self *AvlTree) Size() int { 36 | return self.root.Size() 37 | } 38 | 39 | func (self *AvlTree) Has(key types.Hashable) bool { 40 | return self.root.Has(key) 41 | } 42 | 43 | func (self *AvlTree) Put(key types.Hashable, value interface{}) (err error) { 44 | self.root, _ = self.root.Put(key, value) 45 | return nil 46 | } 47 | 48 | func (self *AvlTree) Get(key types.Hashable) (value interface{}, err error) { 49 | return self.root.Get(key) 50 | } 51 | 52 | func (self *AvlTree) Remove(key types.Hashable) (value interface{}, err error) { 53 | new_root, value, err := self.root.Remove(key) 54 | if err != nil { 55 | return nil, err 56 | } 57 | self.root = new_root 58 | return value, nil 59 | } 60 | 61 | func (self *AvlTree) Iterate() types.KVIterator { 62 | return self.root.Iterate() 63 | } 64 | 65 | func (self *AvlTree) Items() (vi types.KIterator) { 66 | return types.MakeItemsIterator(self) 67 | } 68 | 69 | func (self *AvlTree) Values() types.Iterator { 70 | return self.root.Values() 71 | } 72 | 73 | func (self *AvlTree) Keys() types.KIterator { 74 | return self.root.Keys() 75 | } 76 | 77 | type AvlNode struct { 78 | key types.Hashable 79 | value interface{} 80 | height int 81 | left *AvlNode 82 | right *AvlNode 83 | } 84 | 85 | func (self *AvlNode) Has(key types.Hashable) (has bool) { 86 | if self == nil { 87 | return false 88 | } 89 | if self.key.Equals(key) { 90 | return true 91 | } else if key.Less(self.key) { 92 | return self.left.Has(key) 93 | } else { 94 | return self.right.Has(key) 95 | } 96 | } 97 | 98 | func (self *AvlNode) Get(key types.Hashable) (value interface{}, err error) { 99 | if self == nil { 100 | return nil, errors.NotFound(key) 101 | } 102 | if self.key.Equals(key) { 103 | return self.value, nil 104 | } else if key.Less(self.key) { 105 | return self.left.Get(key) 106 | } else { 107 | return self.right.Get(key) 108 | } 109 | } 110 | 111 | func (self *AvlNode) pop_node(node *AvlNode) *AvlNode { 112 | if node == nil { 113 | panic("node can't be nil") 114 | } else if node.left != nil && node.right != nil { 115 | panic("node must not have both left and right") 116 | } 117 | 118 | if self == nil { 119 | return nil 120 | } else if self == node { 121 | var n *AvlNode 122 | if node.left != nil { 123 | n = node.left 124 | } else if node.right != nil { 125 | n = node.right 126 | } else { 127 | n = nil 128 | } 129 | node.left = nil 130 | node.right = nil 131 | return n 132 | } 133 | 134 | if node.key.Less(self.key) { 135 | self.left = self.left.pop_node(node) 136 | } else { 137 | self.right = self.right.pop_node(node) 138 | } 139 | 140 | self.height = max(self.left.Height(), self.right.Height()) + 1 141 | return self 142 | } 143 | 144 | func (self *AvlNode) push_node(node *AvlNode) *AvlNode { 145 | if node == nil { 146 | panic("node can't be nil") 147 | } else if node.left != nil || node.right != nil { 148 | panic("node now be a leaf") 149 | } 150 | 151 | if self == nil { 152 | node.height = 1 153 | return node 154 | } else if node.key.Less(self.key) { 155 | self.left = self.left.push_node(node) 156 | } else { 157 | self.right = self.right.push_node(node) 158 | } 159 | self.height = max(self.left.Height(), self.right.Height()) + 1 160 | return self 161 | } 162 | 163 | func (self *AvlNode) rotate_right() *AvlNode { 164 | if self == nil { 165 | return self 166 | } 167 | if self.left == nil { 168 | return self 169 | } 170 | new_root := self.left.rmd() 171 | self = self.pop_node(new_root) 172 | new_root.left = self.left 173 | new_root.right = self.right 174 | self.left = nil 175 | self.right = nil 176 | return new_root.push_node(self) 177 | } 178 | 179 | func (self *AvlNode) rotate_left() *AvlNode { 180 | if self == nil { 181 | return self 182 | } 183 | if self.right == nil { 184 | return self 185 | } 186 | new_root := self.right.lmd() 187 | self = self.pop_node(new_root) 188 | new_root.left = self.left 189 | new_root.right = self.right 190 | self.left = nil 191 | self.right = nil 192 | return new_root.push_node(self) 193 | } 194 | 195 | func (self *AvlNode) balance() *AvlNode { 196 | if self == nil { 197 | return self 198 | } 199 | for abs(self.left.Height()-self.right.Height()) > 2 { 200 | if self.left.Height() > self.right.Height() { 201 | self = self.rotate_right() 202 | } else { 203 | self = self.rotate_left() 204 | } 205 | } 206 | return self 207 | } 208 | 209 | func (self *AvlNode) Put(key types.Hashable, value interface{}) (_ *AvlNode, updated bool) { 210 | if self == nil { 211 | return &AvlNode{key: key, value: value, height: 1}, false 212 | } 213 | 214 | if self.key.Equals(key) { 215 | self.value = value 216 | return self, true 217 | } 218 | 219 | if key.Less(self.key) { 220 | self.left, updated = self.left.Put(key, value) 221 | } else { 222 | self.right, updated = self.right.Put(key, value) 223 | } 224 | if !updated { 225 | self.height += 1 226 | return self.balance(), updated 227 | } 228 | return self, updated 229 | } 230 | 231 | func (self *AvlNode) Remove(key types.Hashable) (_ *AvlNode, value interface{}, err error) { 232 | if self == nil { 233 | return nil, nil, errors.NotFound(key) 234 | } 235 | 236 | if self.key.Equals(key) { 237 | if self.left != nil && self.right != nil { 238 | if self.left.Size() < self.right.Size() { 239 | lmd := self.right.lmd() 240 | lmd.left = self.left 241 | return self.right, self.value, nil 242 | } else { 243 | rmd := self.left.rmd() 244 | rmd.right = self.right 245 | return self.left, self.value, nil 246 | } 247 | } else if self.left == nil { 248 | return self.right, self.value, nil 249 | } else if self.right == nil { 250 | return self.left, self.value, nil 251 | } else { 252 | return nil, self.value, nil 253 | } 254 | } 255 | if key.Less(self.key) { 256 | self.left, value, err = self.left.Remove(key) 257 | } else { 258 | self.right, value, err = self.right.Remove(key) 259 | } 260 | if err != nil { 261 | return self.balance(), value, err 262 | } 263 | return self, value, err 264 | } 265 | 266 | func (self *AvlNode) Height() int { 267 | if self == nil { 268 | return 0 269 | } 270 | return self.height 271 | } 272 | 273 | func (self *AvlNode) Size() int { 274 | if self == nil { 275 | return 0 276 | } 277 | return 1 + self.left.Size() + self.right.Size() 278 | } 279 | 280 | func (self *AvlNode) Key() types.Hashable { 281 | return self.key 282 | } 283 | 284 | func (self *AvlNode) Value() interface{} { 285 | return self.value 286 | } 287 | 288 | func (self *AvlNode) Left() types.BinaryTreeNode { 289 | if self.left == nil { 290 | return nil 291 | } 292 | return self.left 293 | } 294 | 295 | func (self *AvlNode) Right() types.BinaryTreeNode { 296 | if self.right == nil { 297 | return nil 298 | } 299 | return self.right 300 | } 301 | 302 | func (self *AvlNode) GetChild(i int) types.TreeNode { 303 | return types.DoGetChild(self, i) 304 | } 305 | 306 | func (self *AvlNode) ChildCount() int { 307 | return types.DoChildCount(self) 308 | } 309 | 310 | func (self *AvlNode) Children() types.TreeNodeIterator { 311 | return types.MakeChildrenIterator(self) 312 | } 313 | 314 | func (self *AvlNode) Iterate() types.KVIterator { 315 | tni := tree.TraverseBinaryTreeInOrder(self) 316 | return types.MakeKVIteratorFromTreeNodeIterator(tni) 317 | } 318 | 319 | func (self *AvlNode) Keys() types.KIterator { 320 | return types.MakeKeysIterator(self) 321 | } 322 | 323 | func (self *AvlNode) Values() types.Iterator { 324 | return types.MakeValuesIterator(self) 325 | } 326 | 327 | func (self *AvlNode) _md(side func(*AvlNode) *AvlNode) *AvlNode { 328 | if self == nil { 329 | return nil 330 | } else if side(self) != nil { 331 | return side(self)._md(side) 332 | } else { 333 | return self 334 | } 335 | } 336 | 337 | func (self *AvlNode) lmd() *AvlNode { 338 | return self._md(func(node *AvlNode) *AvlNode { return node.left }) 339 | } 340 | 341 | func (self *AvlNode) rmd() *AvlNode { 342 | return self._md(func(node *AvlNode) *AvlNode { return node.right }) 343 | } 344 | -------------------------------------------------------------------------------- /vendor/github.com/timtadh/data-structures/tree/avl/imm_avltree.go: -------------------------------------------------------------------------------- 1 | package avl 2 | 3 | import ( 4 | "github.com/timtadh/data-structures/errors" 5 | "github.com/timtadh/data-structures/tree" 6 | "github.com/timtadh/data-structures/types" 7 | ) 8 | 9 | type ImmutableAvlTree struct { 10 | root *ImmutableAvlNode 11 | } 12 | 13 | func NewImmutableAvlTree() *ImmutableAvlTree { 14 | return &ImmutableAvlTree{} 15 | } 16 | 17 | func (self *ImmutableAvlTree) Root() types.TreeNode { 18 | return self.root.Copy() 19 | } 20 | 21 | func (self *ImmutableAvlTree) Size() int { 22 | return self.root.Size() 23 | } 24 | 25 | func (self *ImmutableAvlTree) Has(key types.Hashable) bool { 26 | return self.root.Has(key) 27 | } 28 | 29 | func (self *ImmutableAvlTree) Put(key types.Hashable, value interface{}) (err error) { 30 | self.root, _ = self.root.Put(key, value) 31 | return nil 32 | } 33 | 34 | func (self *ImmutableAvlTree) Get(key types.Hashable) (value interface{}, err error) { 35 | return self.root.Get(key) 36 | } 37 | 38 | func (self *ImmutableAvlTree) Remove(key types.Hashable) (value interface{}, err error) { 39 | new_root, value, err := self.root.Remove(key) 40 | if err != nil { 41 | return nil, err 42 | } 43 | self.root = new_root 44 | return value, nil 45 | } 46 | 47 | func (self *ImmutableAvlTree) Iterate() types.KVIterator { 48 | return self.root.Iterate() 49 | } 50 | 51 | func (self *ImmutableAvlTree) Items() (vi types.KIterator) { 52 | return types.MakeItemsIterator(self) 53 | } 54 | 55 | func (self *ImmutableAvlTree) Values() types.Iterator { 56 | return self.root.Values() 57 | } 58 | 59 | func (self *ImmutableAvlTree) Keys() types.KIterator { 60 | return self.root.Keys() 61 | } 62 | 63 | type ImmutableAvlNode struct { 64 | key types.Hashable 65 | value interface{} 66 | height int 67 | left *ImmutableAvlNode 68 | right *ImmutableAvlNode 69 | } 70 | 71 | func (self *ImmutableAvlNode) Copy() *ImmutableAvlNode { 72 | if self == nil { 73 | return nil 74 | } 75 | return &ImmutableAvlNode{ 76 | key: self.key, 77 | value: self.value, 78 | height: self.height, 79 | left: self.left, 80 | right: self.right, 81 | } 82 | } 83 | 84 | func (self *ImmutableAvlNode) Has(key types.Hashable) (has bool) { 85 | if self == nil { 86 | return false 87 | } 88 | if self.key.Equals(key) { 89 | return true 90 | } else if key.Less(self.key) { 91 | return self.left.Has(key) 92 | } else { 93 | return self.right.Has(key) 94 | } 95 | } 96 | 97 | func (self *ImmutableAvlNode) Get(key types.Hashable) (value interface{}, err error) { 98 | if self == nil { 99 | return nil, errors.NotFound(key) 100 | } 101 | if self.key.Equals(key) { 102 | return self.value, nil 103 | } else if key.Less(self.key) { 104 | return self.left.Get(key) 105 | } else { 106 | return self.right.Get(key) 107 | } 108 | } 109 | 110 | func (self *ImmutableAvlNode) pop_node(node *ImmutableAvlNode) (new_self, new_node *ImmutableAvlNode) { 111 | if node == nil { 112 | panic("node can't be nil") 113 | } else if node.left != nil && node.right != nil { 114 | panic("node must not have both left and right") 115 | } 116 | 117 | if self == nil { 118 | return nil, node.Copy() 119 | } else if self == node { 120 | var n *ImmutableAvlNode 121 | if node.left != nil { 122 | n = node.left 123 | } else if node.right != nil { 124 | n = node.right 125 | } else { 126 | n = nil 127 | } 128 | node = node.Copy() 129 | node.left = nil 130 | node.right = nil 131 | return n, node 132 | } 133 | 134 | self = self.Copy() 135 | 136 | if node.key.Less(self.key) { 137 | self.left, node = self.left.pop_node(node) 138 | } else { 139 | self.right, node = self.right.pop_node(node) 140 | } 141 | 142 | self.height = max(self.left.Height(), self.right.Height()) + 1 143 | return self, node 144 | } 145 | 146 | func (self *ImmutableAvlNode) push_node(node *ImmutableAvlNode) *ImmutableAvlNode { 147 | if node == nil { 148 | panic("node can't be nil") 149 | } else if node.left != nil || node.right != nil { 150 | panic("node must now be a leaf") 151 | } 152 | 153 | self = self.Copy() 154 | 155 | if self == nil { 156 | node.height = 1 157 | return node 158 | } else if node.key.Less(self.key) { 159 | self.left = self.left.push_node(node) 160 | } else { 161 | self.right = self.right.push_node(node) 162 | } 163 | self.height = max(self.left.Height(), self.right.Height()) + 1 164 | return self 165 | } 166 | 167 | func (self *ImmutableAvlNode) rotate_right() *ImmutableAvlNode { 168 | if self == nil { 169 | return self 170 | } 171 | if self.left == nil { 172 | return self 173 | } 174 | return self.rotate(self.left.rmd) 175 | } 176 | 177 | func (self *ImmutableAvlNode) rotate_left() *ImmutableAvlNode { 178 | if self == nil { 179 | return self 180 | } 181 | if self.right == nil { 182 | return self 183 | } 184 | return self.rotate(self.right.lmd) 185 | } 186 | 187 | func (self *ImmutableAvlNode) rotate(get_new_root func() *ImmutableAvlNode) *ImmutableAvlNode { 188 | self, new_root := self.pop_node(get_new_root()) 189 | new_root.left = self.left 190 | new_root.right = self.right 191 | self.left = nil 192 | self.right = nil 193 | return new_root.push_node(self) 194 | } 195 | 196 | func (self *ImmutableAvlNode) balance() *ImmutableAvlNode { 197 | if self == nil { 198 | return self 199 | } 200 | for abs(self.left.Height()-self.right.Height()) > 2 { 201 | if self.left.Height() > self.right.Height() { 202 | self = self.rotate_right() 203 | } else { 204 | self = self.rotate_left() 205 | } 206 | } 207 | return self 208 | } 209 | 210 | func (self *ImmutableAvlNode) Put(key types.Hashable, value interface{}) (_ *ImmutableAvlNode, updated bool) { 211 | if self == nil { 212 | return &ImmutableAvlNode{key: key, value: value, height: 1}, false 213 | } 214 | 215 | self = self.Copy() 216 | 217 | if self.key.Equals(key) { 218 | self.value = value 219 | return self, true 220 | } 221 | 222 | if key.Less(self.key) { 223 | self.left, updated = self.left.Put(key, value) 224 | } else { 225 | self.right, updated = self.right.Put(key, value) 226 | } 227 | self.height = max(self.left.Height(), self.right.Height()) + 1 228 | 229 | if !updated { 230 | self.height += 1 231 | return self.balance(), updated 232 | } 233 | return self, updated 234 | } 235 | 236 | func (self *ImmutableAvlNode) Remove(key types.Hashable) (_ *ImmutableAvlNode, value interface{}, err error) { 237 | if self == nil { 238 | return nil, nil, errors.NotFound(key) 239 | } 240 | 241 | if self.key.Equals(key) { 242 | if self.left != nil && self.right != nil { 243 | var new_root *ImmutableAvlNode 244 | if self.left.Size() < self.right.Size() { 245 | self, new_root = self.pop_node(self.right.lmd()) 246 | } else { 247 | self, new_root = self.pop_node(self.left.rmd()) 248 | } 249 | new_root.left = self.left 250 | new_root.right = self.right 251 | return new_root, self.value, nil 252 | } else if self.left == nil { 253 | return self.right, self.value, nil 254 | } else if self.right == nil { 255 | return self.left, self.value, nil 256 | } else { 257 | return nil, self.value, nil 258 | } 259 | } 260 | 261 | self = self.Copy() 262 | 263 | if key.Less(self.key) { 264 | self.left, value, err = self.left.Remove(key) 265 | } else { 266 | self.right, value, err = self.right.Remove(key) 267 | } 268 | self.height = max(self.left.Height(), self.right.Height()) + 1 269 | if err != nil { 270 | return self.balance(), value, err 271 | } 272 | return self, value, err 273 | } 274 | 275 | func (self *ImmutableAvlNode) Height() int { 276 | if self == nil { 277 | return 0 278 | } 279 | return self.height 280 | } 281 | 282 | func (self *ImmutableAvlNode) Size() int { 283 | if self == nil { 284 | return 0 285 | } 286 | return 1 + self.left.Size() + self.right.Size() 287 | } 288 | 289 | func (self *ImmutableAvlNode) Key() types.Hashable { 290 | return self.key 291 | } 292 | 293 | func (self *ImmutableAvlNode) Value() interface{} { 294 | return self.value 295 | } 296 | 297 | func (self *ImmutableAvlNode) Left() types.BinaryTreeNode { 298 | if self.left == nil { 299 | return nil 300 | } 301 | return self.left 302 | } 303 | 304 | func (self *ImmutableAvlNode) Right() types.BinaryTreeNode { 305 | if self.right == nil { 306 | return nil 307 | } 308 | return self.right 309 | } 310 | 311 | func (self *ImmutableAvlNode) GetChild(i int) types.TreeNode { 312 | return types.DoGetChild(self, i) 313 | } 314 | 315 | func (self *ImmutableAvlNode) ChildCount() int { 316 | return types.DoChildCount(self) 317 | } 318 | 319 | func (self *ImmutableAvlNode) Children() types.TreeNodeIterator { 320 | return types.MakeChildrenIterator(self) 321 | } 322 | 323 | func (self *ImmutableAvlNode) Iterate() types.KVIterator { 324 | tni := tree.TraverseBinaryTreeInOrder(self) 325 | return types.MakeKVIteratorFromTreeNodeIterator(tni) 326 | } 327 | 328 | func (self *ImmutableAvlNode) Keys() types.KIterator { 329 | return types.MakeKeysIterator(self) 330 | } 331 | 332 | func (self *ImmutableAvlNode) Values() types.Iterator { 333 | return types.MakeValuesIterator(self) 334 | } 335 | 336 | func (self *ImmutableAvlNode) _md(side func(*ImmutableAvlNode) *ImmutableAvlNode) *ImmutableAvlNode { 337 | if self == nil { 338 | return nil 339 | } else if side(self) != nil { 340 | return side(self)._md(side) 341 | } else { 342 | return self 343 | } 344 | } 345 | 346 | func (self *ImmutableAvlNode) lmd() *ImmutableAvlNode { 347 | return self._md(func(node *ImmutableAvlNode) *ImmutableAvlNode { return node.left }) 348 | } 349 | 350 | func (self *ImmutableAvlNode) rmd() *ImmutableAvlNode { 351 | return self._md(func(node *ImmutableAvlNode) *ImmutableAvlNode { return node.right }) 352 | } 353 | -------------------------------------------------------------------------------- /vendor/github.com/timtadh/data-structures/tree/util.go: -------------------------------------------------------------------------------- 1 | package tree 2 | 3 | import ( 4 | "github.com/timtadh/data-structures/types" 5 | ) 6 | 7 | func pop(stack []types.TreeNode) ([]types.TreeNode, types.TreeNode) { 8 | if len(stack) <= 0 { 9 | return stack, nil 10 | } else { 11 | return stack[0 : len(stack)-1], stack[len(stack)-1] 12 | } 13 | } 14 | 15 | func btn_expose_nil(node types.BinaryTreeNode) types.BinaryTreeNode { 16 | if types.IsNil(node) { 17 | return nil 18 | } 19 | return node 20 | } 21 | 22 | func tn_expose_nil(node types.TreeNode) types.TreeNode { 23 | if types.IsNil(node) { 24 | return nil 25 | } 26 | return node 27 | } 28 | 29 | func TraverseBinaryTreeInOrder(node types.BinaryTreeNode) types.TreeNodeIterator { 30 | stack := make([]types.TreeNode, 0, 10) 31 | var cur types.TreeNode = btn_expose_nil(node) 32 | var tn_iterator types.TreeNodeIterator 33 | tn_iterator = func() (tn types.TreeNode, next types.TreeNodeIterator) { 34 | if len(stack) > 0 || cur != nil { 35 | for cur != nil { 36 | stack = append(stack, cur) 37 | cur = cur.(types.BinaryTreeNode).Left() 38 | } 39 | stack, cur = pop(stack) 40 | tn = cur 41 | cur = cur.(types.BinaryTreeNode).Right() 42 | return tn, tn_iterator 43 | } else { 44 | return nil, nil 45 | } 46 | } 47 | return tn_iterator 48 | } 49 | 50 | func TraverseTreePreOrder(node types.TreeNode) types.TreeNodeIterator { 51 | stack := append(make([]types.TreeNode, 0, 10), tn_expose_nil(node)) 52 | var tn_iterator types.TreeNodeIterator 53 | tn_iterator = func() (tn types.TreeNode, next types.TreeNodeIterator) { 54 | if len(stack) <= 0 { 55 | return nil, nil 56 | } 57 | stack, tn = pop(stack) 58 | kid_count := 1 59 | if tn.ChildCount() >= 0 { 60 | kid_count = tn.ChildCount() 61 | } 62 | kids := make([]types.TreeNode, 0, kid_count) 63 | for child, next := tn.Children()(); next != nil; child, next = next() { 64 | kids = append(kids, child) 65 | } 66 | for i := len(kids) - 1; i >= 0; i-- { 67 | stack = append(stack, kids[i]) 68 | } 69 | return tn, tn_iterator 70 | } 71 | return tn_iterator 72 | } 73 | 74 | func TraverseTreePostOrder(node types.TreeNode) types.TreeNodeIterator { 75 | type entry struct { 76 | tn types.TreeNode 77 | i int 78 | } 79 | 80 | pop := func(stack []entry) ([]entry, types.TreeNode, int) { 81 | if len(stack) <= 0 { 82 | return stack, nil, 0 83 | } else { 84 | e := stack[len(stack)-1] 85 | return stack[0 : len(stack)-1], e.tn, e.i 86 | } 87 | } 88 | 89 | stack := append(make([]entry, 0, 10), entry{tn_expose_nil(node), 0}) 90 | 91 | var tn_iterator types.TreeNodeIterator 92 | tn_iterator = func() (tn types.TreeNode, next types.TreeNodeIterator) { 93 | var i int 94 | 95 | if len(stack) <= 0 { 96 | return nil, nil 97 | } 98 | 99 | stack, tn, i = pop(stack) 100 | for i < tn.ChildCount() { 101 | kid := tn.GetChild(i) 102 | stack = append(stack, entry{tn, i + 1}) 103 | tn = kid 104 | i = 0 105 | } 106 | return tn, tn_iterator 107 | } 108 | return tn_iterator 109 | } 110 | -------------------------------------------------------------------------------- /vendor/github.com/timtadh/data-structures/types/int.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "encoding/binary" 5 | ) 6 | 7 | import ( 8 | "github.com/timtadh/data-structures/errors" 9 | ) 10 | 11 | type Int8 int8 12 | type UInt8 uint8 13 | type Int16 int16 14 | type UInt16 uint16 15 | type Int32 int32 16 | type UInt32 uint32 17 | type Int64 int64 18 | type UInt64 uint64 19 | type Int int 20 | type UInt uint 21 | 22 | func (self *Int8) MarshalBinary() ([]byte, error) { 23 | bytes := make([]byte, 0) 24 | bytes[0] = uint8(*self) 25 | return bytes, nil 26 | } 27 | 28 | func (self *Int8) UnmarshalBinary(data []byte) error { 29 | if len(data) != 1 { 30 | return errors.Errorf("data wrong size") 31 | } 32 | *self = Int8(data[0]) 33 | return nil 34 | } 35 | 36 | func (self Int8) Equals(other Equatable) bool { 37 | if o, ok := other.(Int8); ok { 38 | return self == o 39 | } else { 40 | return false 41 | } 42 | } 43 | 44 | func (self Int8) Less(other Sortable) bool { 45 | if o, ok := other.(Int8); ok { 46 | return self < o 47 | } else { 48 | return false 49 | } 50 | } 51 | 52 | func (self Int8) Hash() int { 53 | return int(self) 54 | } 55 | 56 | func (self *UInt8) MarshalBinary() ([]byte, error) { 57 | bytes := make([]byte, 0) 58 | bytes[0] = uint8(*self) 59 | return bytes, nil 60 | } 61 | 62 | func (self *UInt8) UnmarshalBinary(data []byte) error { 63 | if len(data) != 1 { 64 | return errors.Errorf("data wrong size") 65 | } 66 | *self = UInt8(data[0]) 67 | return nil 68 | } 69 | 70 | func (self UInt8) Equals(other Equatable) bool { 71 | if o, ok := other.(UInt8); ok { 72 | return self == o 73 | } else { 74 | return false 75 | } 76 | } 77 | 78 | func (self UInt8) Less(other Sortable) bool { 79 | if o, ok := other.(UInt8); ok { 80 | return self < o 81 | } else { 82 | return false 83 | } 84 | } 85 | 86 | func (self UInt8) Hash() int { 87 | return int(self) 88 | } 89 | 90 | func (self *Int16) MarshalBinary() ([]byte, error) { 91 | bytes := make([]byte, 2) 92 | binary.BigEndian.PutUint16(bytes, uint16(*self)) 93 | return bytes, nil 94 | } 95 | 96 | func (self *Int16) UnmarshalBinary(data []byte) error { 97 | if len(data) != 2 { 98 | return errors.Errorf("data wrong size") 99 | } 100 | *self = Int16(binary.BigEndian.Uint16(data)) 101 | return nil 102 | } 103 | 104 | func (self Int16) Equals(other Equatable) bool { 105 | if o, ok := other.(Int16); ok { 106 | return self == o 107 | } else { 108 | return false 109 | } 110 | } 111 | 112 | func (self Int16) Less(other Sortable) bool { 113 | if o, ok := other.(Int16); ok { 114 | return self < o 115 | } else { 116 | return false 117 | } 118 | } 119 | 120 | func (self Int16) Hash() int { 121 | return int(self) 122 | } 123 | 124 | func (self *UInt16) MarshalBinary() ([]byte, error) { 125 | bytes := make([]byte, 2) 126 | binary.BigEndian.PutUint16(bytes, uint16(*self)) 127 | return bytes, nil 128 | } 129 | 130 | func (self *UInt16) UnmarshalBinary(data []byte) error { 131 | if len(data) != 2 { 132 | return errors.Errorf("data wrong size") 133 | } 134 | *self = UInt16(binary.BigEndian.Uint16(data)) 135 | return nil 136 | } 137 | 138 | func (self UInt16) Equals(other Equatable) bool { 139 | if o, ok := other.(UInt16); ok { 140 | return self == o 141 | } else { 142 | return false 143 | } 144 | } 145 | 146 | func (self UInt16) Less(other Sortable) bool { 147 | if o, ok := other.(UInt16); ok { 148 | return self < o 149 | } else { 150 | return false 151 | } 152 | } 153 | 154 | func (self UInt16) Hash() int { 155 | return int(self) 156 | } 157 | 158 | func (self *Int32) MarshalBinary() ([]byte, error) { 159 | bytes := make([]byte, 4) 160 | binary.BigEndian.PutUint32(bytes, uint32(*self)) 161 | return bytes, nil 162 | } 163 | 164 | func (self *Int32) UnmarshalBinary(data []byte) error { 165 | if len(data) != 4 { 166 | return errors.Errorf("data wrong size") 167 | } 168 | *self = Int32(binary.BigEndian.Uint32(data)) 169 | return nil 170 | } 171 | 172 | func (self Int32) Equals(other Equatable) bool { 173 | if o, ok := other.(Int32); ok { 174 | return self == o 175 | } else { 176 | return false 177 | } 178 | } 179 | 180 | func (self Int32) Less(other Sortable) bool { 181 | if o, ok := other.(Int32); ok { 182 | return self < o 183 | } else { 184 | return false 185 | } 186 | } 187 | 188 | func (self *UInt32) MarshalBinary() ([]byte, error) { 189 | bytes := make([]byte, 4) 190 | binary.BigEndian.PutUint32(bytes, uint32(*self)) 191 | return bytes, nil 192 | } 193 | 194 | func (self *UInt32) UnmarshalBinary(data []byte) error { 195 | if len(data) != 4 { 196 | return errors.Errorf("data wrong size") 197 | } 198 | *self = UInt32(binary.BigEndian.Uint32(data)) 199 | return nil 200 | } 201 | 202 | func (self Int32) Hash() int { 203 | return int(self) 204 | } 205 | 206 | func (self UInt32) Equals(other Equatable) bool { 207 | if o, ok := other.(UInt32); ok { 208 | return self == o 209 | } else { 210 | return false 211 | } 212 | } 213 | 214 | func (self UInt32) Less(other Sortable) bool { 215 | if o, ok := other.(UInt32); ok { 216 | return self < o 217 | } else { 218 | return false 219 | } 220 | } 221 | 222 | func (self UInt32) Hash() int { 223 | return int(self) 224 | } 225 | 226 | func (self *Int64) MarshalBinary() ([]byte, error) { 227 | bytes := make([]byte, 8) 228 | binary.BigEndian.PutUint64(bytes, uint64(*self)) 229 | return bytes, nil 230 | } 231 | 232 | func (self *Int64) UnmarshalBinary(data []byte) error { 233 | if len(data) != 8 { 234 | return errors.Errorf("data wrong size") 235 | } 236 | *self = Int64(binary.BigEndian.Uint64(data)) 237 | return nil 238 | } 239 | 240 | func (self Int64) Equals(other Equatable) bool { 241 | if o, ok := other.(Int64); ok { 242 | return self == o 243 | } else { 244 | return false 245 | } 246 | } 247 | 248 | func (self Int64) Less(other Sortable) bool { 249 | if o, ok := other.(Int64); ok { 250 | return self < o 251 | } else { 252 | return false 253 | } 254 | } 255 | 256 | func (self Int64) Hash() int { 257 | return int(self>>32) ^ int(self) 258 | } 259 | 260 | func (self *UInt64) MarshalBinary() ([]byte, error) { 261 | bytes := make([]byte, 8) 262 | binary.BigEndian.PutUint64(bytes, uint64(*self)) 263 | return bytes, nil 264 | } 265 | 266 | func (self *UInt64) UnmarshalBinary(data []byte) error { 267 | if len(data) != 8 { 268 | return errors.Errorf("data wrong size") 269 | } 270 | *self = UInt64(binary.BigEndian.Uint64(data)) 271 | return nil 272 | } 273 | 274 | func (self UInt64) Equals(other Equatable) bool { 275 | if o, ok := other.(UInt64); ok { 276 | return self == o 277 | } else { 278 | return false 279 | } 280 | } 281 | 282 | func (self UInt64) Less(other Sortable) bool { 283 | if o, ok := other.(UInt64); ok { 284 | return self < o 285 | } else { 286 | return false 287 | } 288 | } 289 | 290 | func (self UInt64) Hash() int { 291 | return int(self>>32) ^ int(self) 292 | } 293 | 294 | func (self *Int) MarshalBinary() ([]byte, error) { 295 | bytes := make([]byte, 4) 296 | binary.BigEndian.PutUint32(bytes, uint32(*self)) 297 | return bytes, nil 298 | } 299 | 300 | func (self *Int) UnmarshalBinary(data []byte) error { 301 | if len(data) != 4 { 302 | return errors.Errorf("data wrong size") 303 | } 304 | *self = Int(binary.BigEndian.Uint32(data)) 305 | return nil 306 | } 307 | 308 | func (self Int) Equals(other Equatable) bool { 309 | if o, ok := other.(Int); ok { 310 | return self == o 311 | } else { 312 | return false 313 | } 314 | } 315 | 316 | func (self Int) Less(other Sortable) bool { 317 | if o, ok := other.(Int); ok { 318 | return self < o 319 | } else { 320 | return false 321 | } 322 | } 323 | 324 | func (self Int) Hash() int { 325 | return int(self) 326 | } 327 | 328 | func (self *UInt) MarshalBinary() ([]byte, error) { 329 | bytes := make([]byte, 4) 330 | binary.BigEndian.PutUint32(bytes, uint32(*self)) 331 | return bytes, nil 332 | } 333 | 334 | func (self *UInt) UnmarshalBinary(data []byte) error { 335 | if len(data) != 4 { 336 | return errors.Errorf("data wrong size") 337 | } 338 | *self = UInt(binary.BigEndian.Uint32(data)) 339 | return nil 340 | } 341 | 342 | func (self UInt) Equals(other Equatable) bool { 343 | if o, ok := other.(UInt); ok { 344 | return self == o 345 | } else { 346 | return false 347 | } 348 | } 349 | 350 | func (self UInt) Less(other Sortable) bool { 351 | if o, ok := other.(UInt); ok { 352 | return self < o 353 | } else { 354 | return false 355 | } 356 | } 357 | 358 | func (self UInt) Hash() int { 359 | return int(self) 360 | } 361 | -------------------------------------------------------------------------------- /vendor/github.com/timtadh/data-structures/types/map_entry.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type MapEntry struct { 8 | Key Hashable 9 | Value interface{} 10 | } 11 | 12 | func (m *MapEntry) Equals(other Equatable) bool { 13 | if o, ok := other.(*MapEntry); ok { 14 | return m.Key.Equals(o.Key) 15 | } else { 16 | return m.Key.Equals(other) 17 | } 18 | } 19 | 20 | func (m *MapEntry) Less(other Sortable) bool { 21 | if o, ok := other.(*MapEntry); ok { 22 | return m.Key.Less(o.Key) 23 | } else { 24 | return m.Key.Less(other) 25 | } 26 | } 27 | 28 | func (m *MapEntry) Hash() int { 29 | return m.Key.Hash() 30 | } 31 | 32 | func (m *MapEntry) String() string { 33 | return fmt.Sprintf("", m.Key, m.Value) 34 | } 35 | -------------------------------------------------------------------------------- /vendor/github.com/timtadh/data-structures/types/string.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "bytes" 5 | "hash/fnv" 6 | ) 7 | 8 | type String string 9 | type ByteSlice []byte 10 | 11 | func (self *String) MarshalBinary() ([]byte, error) { 12 | return []byte(*self), nil 13 | } 14 | 15 | func (self *String) UnmarshalBinary(data []byte) error { 16 | *self = String(data) 17 | return nil 18 | } 19 | 20 | func (self String) Equals(other Equatable) bool { 21 | if o, ok := other.(String); ok { 22 | return self == o 23 | } else { 24 | return false 25 | } 26 | } 27 | 28 | func (self String) Less(other Sortable) bool { 29 | if o, ok := other.(String); ok { 30 | return self < o 31 | } else { 32 | return false 33 | } 34 | } 35 | 36 | func (self String) Hash() int { 37 | h := fnv.New32a() 38 | h.Write([]byte(string(self))) 39 | return int(h.Sum32()) 40 | } 41 | 42 | func (self *ByteSlice) MarshalBinary() ([]byte, error) { 43 | return []byte(*self), nil 44 | } 45 | 46 | func (self *ByteSlice) UnmarshalBinary(data []byte) error { 47 | *self = ByteSlice(data) 48 | return nil 49 | } 50 | 51 | func (self ByteSlice) Equals(other Equatable) bool { 52 | if o, ok := other.(ByteSlice); ok { 53 | return bytes.Equal(self, o) 54 | } else { 55 | return false 56 | } 57 | } 58 | 59 | func (self ByteSlice) Less(other Sortable) bool { 60 | if o, ok := other.(ByteSlice); ok { 61 | return bytes.Compare(self, o) < 0 // -1 if a < b 62 | } else { 63 | return false 64 | } 65 | } 66 | 67 | func (self ByteSlice) Hash() int { 68 | h := fnv.New32a() 69 | h.Write([]byte(self)) 70 | return int(h.Sum32()) 71 | } 72 | -------------------------------------------------------------------------------- /vendor/github.com/timtadh/data-structures/types/types.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | type Equatable interface { 4 | Equals(b Equatable) bool 5 | } 6 | 7 | type Sortable interface { 8 | Equatable 9 | Less(b Sortable) bool 10 | } 11 | 12 | type Hashable interface { 13 | Sortable 14 | Hash() int 15 | } 16 | 17 | type Marshaler interface { 18 | MarshalBinary() (data []byte, err error) 19 | UnmarshalBinary(data []byte) error 20 | } 21 | 22 | type MHashable interface { 23 | Hashable 24 | Marshaler 25 | } 26 | 27 | type ItemMarshal func(Hashable) ([]byte, error) 28 | type ItemUnmarshal func([]byte) (Hashable, error) 29 | 30 | type Iterator func() (item interface{}, next Iterator) 31 | type KIterator func() (key Hashable, next KIterator) 32 | type KVIterator func() (key Hashable, value interface{}, next KVIterator) 33 | type Coroutine func(send interface{}) (recv interface{}, next Coroutine) 34 | 35 | type Iterable interface { 36 | Iterate() Iterator 37 | } 38 | 39 | type KIterable interface { 40 | Keys() KIterator 41 | } 42 | 43 | type VIterable interface { 44 | Values() Iterator 45 | } 46 | 47 | type KVIterable interface { 48 | Iterate() KVIterator 49 | } 50 | 51 | type MapIterable interface { 52 | KIterable 53 | VIterable 54 | KVIterable 55 | } 56 | 57 | type Sized interface { 58 | Size() int 59 | } 60 | 61 | type MapOperable interface { 62 | Sized 63 | Has(key Hashable) bool 64 | Put(key Hashable, value interface{}) (err error) 65 | Get(key Hashable) (value interface{}, err error) 66 | Remove(key Hashable) (value interface{}, err error) 67 | } 68 | 69 | type WhereFunc func(value interface{}) bool 70 | 71 | type MultiMapOperable interface { 72 | Sized 73 | Has(key Hashable) bool 74 | Count(key Hashable) int 75 | Add(key Hashable, value interface{}) (err error) 76 | Replace(key Hashable, where WhereFunc, value interface{}) (err error) 77 | Find(key Hashable) KVIterator 78 | RemoveWhere(key Hashable, where WhereFunc) (err error) 79 | } 80 | 81 | type Map interface { 82 | MapIterable 83 | MapOperable 84 | } 85 | 86 | type MultiMap interface { 87 | MapIterable 88 | MultiMapOperable 89 | } 90 | 91 | type ContainerOperable interface { 92 | Has(item Hashable) bool 93 | } 94 | 95 | type ItemsOperable interface { 96 | Sized 97 | ContainerOperable 98 | Item(item Hashable) (Hashable, error) 99 | Add(item Hashable) (err error) 100 | Delete(item Hashable) (err error) 101 | Extend(items KIterator) (err error) 102 | } 103 | 104 | type OrderedOperable interface { 105 | Get(i int) (item Hashable, err error) 106 | Find(item Hashable) (idx int, has bool, err error) 107 | } 108 | 109 | type ListIterable interface { 110 | Items() KIterator 111 | } 112 | 113 | type IterableContainer interface { 114 | Sized 115 | ListIterable 116 | Has(item Hashable) bool 117 | } 118 | 119 | type StackOperable interface { 120 | Push(item Hashable) (err error) 121 | Pop() (item Hashable, err error) 122 | } 123 | 124 | type DequeOperable interface { 125 | EnqueFront(item Hashable) (err error) 126 | EnqueBack(item Hashable) (err error) 127 | DequeFront() (item Hashable, err error) 128 | DequeBack() (item Hashable, err error) 129 | First() (item Hashable) 130 | Last() (item Hashable) 131 | } 132 | 133 | type LinkedOperable interface { 134 | Sized 135 | ContainerOperable 136 | StackOperable 137 | DequeOperable 138 | } 139 | 140 | type ListOperable interface { 141 | Sized 142 | ContainerOperable 143 | Append(item Hashable) (err error) 144 | Get(i int) (item Hashable, err error) 145 | Set(i int, item Hashable) (err error) 146 | Insert(i int, item Hashable) (err error) 147 | Remove(i int) (err error) 148 | } 149 | 150 | type OrderedList interface { 151 | ListIterable 152 | OrderedOperable 153 | } 154 | 155 | type Set interface { 156 | Equatable 157 | ListIterable 158 | ItemsOperable 159 | Union(Set) (Set, error) 160 | Intersect(Set) (Set, error) 161 | Subtract(Set) (Set, error) 162 | Subset(Set) bool 163 | Superset(Set) bool 164 | ProperSubset(Set) bool 165 | ProperSuperset(Set) bool 166 | } 167 | 168 | type List interface { 169 | ListIterable 170 | ListOperable 171 | } 172 | 173 | type HList interface { 174 | Hashable 175 | List 176 | } 177 | 178 | type Stack interface { 179 | Sized 180 | ContainerOperable 181 | StackOperable 182 | } 183 | 184 | type Deque interface { 185 | Sized 186 | ContainerOperable 187 | DequeOperable 188 | } 189 | 190 | type Linked interface { 191 | LinkedOperable 192 | ListIterable 193 | } 194 | 195 | type Tree interface { 196 | Root() TreeNode 197 | } 198 | 199 | type TreeMap interface { 200 | Tree 201 | Map 202 | } 203 | 204 | type TreeNode interface { 205 | Key() Hashable 206 | Value() interface{} 207 | Children() TreeNodeIterator 208 | GetChild(int) TreeNode // if your tree can't support this simply panic 209 | // many of the utility functions do not require this 210 | // however, it is recommended that you implement it 211 | // if possible (for instance, post-order traversal 212 | // requires it). 213 | ChildCount() int // a negative value indicates this tree can't provide 214 | // an accurate count. 215 | } 216 | type TreeNodeIterator func() (node TreeNode, next TreeNodeIterator) 217 | 218 | type BinaryTreeNode interface { 219 | TreeNode 220 | Left() BinaryTreeNode 221 | Right() BinaryTreeNode 222 | } 223 | -------------------------------------------------------------------------------- /vendor/github.com/timtadh/data-structures/types/util.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "reflect" 5 | ) 6 | 7 | func IsNil(object interface{}) bool { 8 | return object == nil || reflect.ValueOf(object).IsNil() 9 | } 10 | 11 | func MakeKVIteratorFromTreeNodeIterator(tni TreeNodeIterator) KVIterator { 12 | var kv_iterator KVIterator 13 | kv_iterator = func() (key Hashable, value interface{}, next KVIterator) { 14 | var tn TreeNode 15 | tn, tni = tni() 16 | if tni == nil { 17 | return nil, nil, nil 18 | } 19 | return tn.Key(), tn.Value(), kv_iterator 20 | } 21 | return kv_iterator 22 | } 23 | 24 | func ChainTreeNodeIterators(tnis ...TreeNodeIterator) TreeNodeIterator { 25 | var make_tni func(int) TreeNodeIterator 26 | make_tni = func(i int) (tni_iterator TreeNodeIterator) { 27 | if i >= len(tnis) { 28 | return nil 29 | } 30 | var next TreeNodeIterator = tnis[i] 31 | tni_iterator = func() (TreeNode, TreeNodeIterator) { 32 | var tn TreeNode 33 | tn, next = next() 34 | if next == nil { 35 | tni := make_tni(i + 1) 36 | if tni == nil { 37 | return nil, nil 38 | } else { 39 | return tni() 40 | } 41 | } 42 | return tn, tni_iterator 43 | } 44 | return tni_iterator 45 | } 46 | return make_tni(0) 47 | } 48 | 49 | func MakeKeysIterator(obj KVIterable) KIterator { 50 | kv_iterator := obj.Iterate() 51 | var k_iterator KIterator 52 | k_iterator = func() (key Hashable, next KIterator) { 53 | key, _, kv_iterator = kv_iterator() 54 | if kv_iterator == nil { 55 | return nil, nil 56 | } 57 | return key, k_iterator 58 | } 59 | return k_iterator 60 | } 61 | 62 | func MakeValuesIterator(obj KVIterable) Iterator { 63 | kv_iterator := obj.Iterate() 64 | var v_iterator Iterator 65 | v_iterator = func() (value interface{}, next Iterator) { 66 | _, value, kv_iterator = kv_iterator() 67 | if kv_iterator == nil { 68 | return nil, nil 69 | } 70 | return value, v_iterator 71 | } 72 | return v_iterator 73 | } 74 | 75 | func MakeItemsIterator(obj KVIterable) (kit KIterator) { 76 | kv_iterator := obj.Iterate() 77 | kit = func() (item Hashable, next KIterator) { 78 | var key Hashable 79 | var value interface{} 80 | key, value, kv_iterator = kv_iterator() 81 | if kv_iterator == nil { 82 | return nil, nil 83 | } 84 | return &MapEntry{key, value}, kit 85 | } 86 | return kit 87 | } 88 | 89 | func make_child_slice(node BinaryTreeNode) []BinaryTreeNode { 90 | nodes := make([]BinaryTreeNode, 0, 2) 91 | if !IsNil(node) { 92 | if !IsNil(node.Left()) { 93 | nodes = append(nodes, node.Left()) 94 | } 95 | if !IsNil(node.Right()) { 96 | nodes = append(nodes, node.Right()) 97 | } 98 | } 99 | return nodes 100 | } 101 | 102 | func DoGetChild(node BinaryTreeNode, i int) TreeNode { 103 | return make_child_slice(node)[i] 104 | } 105 | 106 | func DoChildCount(node BinaryTreeNode) int { 107 | return len(make_child_slice(node)) 108 | } 109 | 110 | func MakeChildrenIterator(node BinaryTreeNode) TreeNodeIterator { 111 | nodes := make_child_slice(node) 112 | var make_tn_iterator func(int) TreeNodeIterator 113 | make_tn_iterator = func(i int) TreeNodeIterator { 114 | return func() (kid TreeNode, next TreeNodeIterator) { 115 | if i < len(nodes) { 116 | return nodes[i], make_tn_iterator(i + 1) 117 | } 118 | return nil, nil 119 | } 120 | } 121 | return make_tn_iterator(0) 122 | } 123 | 124 | func MakeMarshals(empty func() MHashable) (ItemMarshal, ItemUnmarshal) { 125 | marshal := func(item Hashable) ([]byte, error) { 126 | i := item.(Marshaler) 127 | return i.MarshalBinary() 128 | } 129 | unmarshal := func(bytes []byte) (Hashable, error) { 130 | i := empty() 131 | err := i.UnmarshalBinary(bytes) 132 | if err != nil { 133 | return nil, err 134 | } 135 | return i, nil 136 | } 137 | return marshal, unmarshal 138 | } 139 | 140 | func Int8Marshals() (ItemMarshal, ItemUnmarshal) { 141 | marshal := func(item Hashable) ([]byte, error) { 142 | i := item.(Int8) 143 | return i.MarshalBinary() 144 | } 145 | unmarshal := func(bytes []byte) (Hashable, error) { 146 | i := Int8(0) 147 | err := i.UnmarshalBinary(bytes) 148 | if err != nil { 149 | return nil, err 150 | } 151 | return i, nil 152 | } 153 | return marshal, unmarshal 154 | } 155 | 156 | func UInt8Marshals() (ItemMarshal, ItemUnmarshal) { 157 | marshal := func(item Hashable) ([]byte, error) { 158 | i := item.(UInt8) 159 | return i.MarshalBinary() 160 | } 161 | unmarshal := func(bytes []byte) (Hashable, error) { 162 | i := UInt8(0) 163 | err := i.UnmarshalBinary(bytes) 164 | if err != nil { 165 | return nil, err 166 | } 167 | return i, nil 168 | } 169 | return marshal, unmarshal 170 | } 171 | 172 | func Int16Marshals() (ItemMarshal, ItemUnmarshal) { 173 | marshal := func(item Hashable) ([]byte, error) { 174 | i := item.(Int16) 175 | return i.MarshalBinary() 176 | } 177 | unmarshal := func(bytes []byte) (Hashable, error) { 178 | i := Int16(0) 179 | err := i.UnmarshalBinary(bytes) 180 | if err != nil { 181 | return nil, err 182 | } 183 | return i, nil 184 | } 185 | return marshal, unmarshal 186 | } 187 | 188 | func UInt16Marshals() (ItemMarshal, ItemUnmarshal) { 189 | marshal := func(item Hashable) ([]byte, error) { 190 | i := item.(UInt16) 191 | return i.MarshalBinary() 192 | } 193 | unmarshal := func(bytes []byte) (Hashable, error) { 194 | i := UInt16(0) 195 | err := i.UnmarshalBinary(bytes) 196 | if err != nil { 197 | return nil, err 198 | } 199 | return i, nil 200 | } 201 | return marshal, unmarshal 202 | } 203 | 204 | func Int32Marshals() (ItemMarshal, ItemUnmarshal) { 205 | marshal := func(item Hashable) ([]byte, error) { 206 | i := item.(Int32) 207 | return i.MarshalBinary() 208 | } 209 | unmarshal := func(bytes []byte) (Hashable, error) { 210 | i := Int32(0) 211 | err := i.UnmarshalBinary(bytes) 212 | if err != nil { 213 | return nil, err 214 | } 215 | return i, nil 216 | } 217 | return marshal, unmarshal 218 | } 219 | 220 | func UInt32Marshals() (ItemMarshal, ItemUnmarshal) { 221 | marshal := func(item Hashable) ([]byte, error) { 222 | i := item.(UInt32) 223 | return i.MarshalBinary() 224 | } 225 | unmarshal := func(bytes []byte) (Hashable, error) { 226 | i := UInt32(0) 227 | err := i.UnmarshalBinary(bytes) 228 | if err != nil { 229 | return nil, err 230 | } 231 | return i, nil 232 | } 233 | return marshal, unmarshal 234 | } 235 | 236 | func Int64Marshals() (ItemMarshal, ItemUnmarshal) { 237 | marshal := func(item Hashable) ([]byte, error) { 238 | i := item.(Int64) 239 | return i.MarshalBinary() 240 | } 241 | unmarshal := func(bytes []byte) (Hashable, error) { 242 | i := Int64(0) 243 | err := i.UnmarshalBinary(bytes) 244 | if err != nil { 245 | return nil, err 246 | } 247 | return i, nil 248 | } 249 | return marshal, unmarshal 250 | } 251 | 252 | func UInt64Marshals() (ItemMarshal, ItemUnmarshal) { 253 | marshal := func(item Hashable) ([]byte, error) { 254 | i := item.(UInt64) 255 | return i.MarshalBinary() 256 | } 257 | unmarshal := func(bytes []byte) (Hashable, error) { 258 | i := UInt64(0) 259 | err := i.UnmarshalBinary(bytes) 260 | if err != nil { 261 | return nil, err 262 | } 263 | return i, nil 264 | } 265 | return marshal, unmarshal 266 | } 267 | 268 | func IntMarshals() (ItemMarshal, ItemUnmarshal) { 269 | marshal := func(item Hashable) ([]byte, error) { 270 | i := item.(Int) 271 | return i.MarshalBinary() 272 | } 273 | unmarshal := func(bytes []byte) (Hashable, error) { 274 | i := Int(0) 275 | err := i.UnmarshalBinary(bytes) 276 | if err != nil { 277 | return nil, err 278 | } 279 | return i, nil 280 | } 281 | return marshal, unmarshal 282 | } 283 | 284 | func UIntMarshals() (ItemMarshal, ItemUnmarshal) { 285 | marshal := func(item Hashable) ([]byte, error) { 286 | i := item.(UInt) 287 | return i.MarshalBinary() 288 | } 289 | unmarshal := func(bytes []byte) (Hashable, error) { 290 | i := UInt(0) 291 | err := i.UnmarshalBinary(bytes) 292 | if err != nil { 293 | return nil, err 294 | } 295 | return i, nil 296 | } 297 | return marshal, unmarshal 298 | } 299 | 300 | func StringMarshals() (ItemMarshal, ItemUnmarshal) { 301 | marshal := func(item Hashable) ([]byte, error) { 302 | i := item.(String) 303 | return i.MarshalBinary() 304 | } 305 | unmarshal := func(bytes []byte) (Hashable, error) { 306 | i := String("") 307 | err := i.UnmarshalBinary(bytes) 308 | if err != nil { 309 | return nil, err 310 | } 311 | return i, nil 312 | } 313 | return marshal, unmarshal 314 | } 315 | 316 | func ByteSliceMarshals() (ItemMarshal, ItemUnmarshal) { 317 | marshal := func(item Hashable) ([]byte, error) { 318 | return []byte(item.(ByteSlice)), nil 319 | } 320 | unmarshal := func(bytes []byte) (Hashable, error) { 321 | return ByteSlice(bytes), nil 322 | } 323 | return marshal, unmarshal 324 | } 325 | -------------------------------------------------------------------------------- /vendor/github.com/timtadh/lexmachine/.activate: -------------------------------------------------------------------------------- 1 | export GOPATH=$(readlink -e $(pwd)/../../../..) 2 | export PATH=$GOPATH/bin:$PATH 3 | -------------------------------------------------------------------------------- /vendor/github.com/timtadh/lexmachine/.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | *.swo 3 | bin 4 | pkg 5 | vendor 6 | -------------------------------------------------------------------------------- /vendor/github.com/timtadh/lexmachine/.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "src/github.com/timtadh/getopt"] 2 | path = src/github.com/timtadh/getopt 3 | url = git@github.com:timtadh/getopt.git 4 | [submodule "src/github.com/timtadh/data-structures"] 5 | path = src/github.com/timtadh/data-structures 6 | url = git@github.com:timtadh/data-structures.git 7 | -------------------------------------------------------------------------------- /vendor/github.com/timtadh/lexmachine/CHANGELOG: -------------------------------------------------------------------------------- 1 | ## 0.2.1 2 | 3 | - Fixed regression bugs in new DFA backend 4 | 5 | ## 0.2.0 6 | 7 | - Added DFA backend 8 | - Improved documentation 9 | - Fixed lint issues 10 | 11 | ## 0.1.1 12 | 13 | - Improved regex parser 14 | - Added documentation 15 | 16 | ## 0.1.0 initial release 17 | -------------------------------------------------------------------------------- /vendor/github.com/timtadh/lexmachine/Gopkg.lock: -------------------------------------------------------------------------------- 1 | # This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. 2 | 3 | 4 | [[projects]] 5 | name = "github.com/timtadh/data-structures" 6 | packages = ["errors","hashtable","linked","list","rand","set","test","tree","tree/avl","types"] 7 | revision = "cd0c1de5390876f92ce0762c9c626a569b124f24" 8 | version = "v0.5.2" 9 | 10 | [[projects]] 11 | name = "github.com/timtadh/getopt" 12 | packages = ["."] 13 | revision = "29f1208d827b977f2e4060ca9923032b34094187" 14 | version = "v1.0.0" 15 | 16 | [solve-meta] 17 | analyzer-name = "dep" 18 | analyzer-version = 1 19 | inputs-digest = "76403af9b8313eb4c8dec248b6daa284bd8bf99ca2aebb7c22bd1b5ad203cb65" 20 | solver-name = "gps-cdcl" 21 | solver-version = 1 22 | -------------------------------------------------------------------------------- /vendor/github.com/timtadh/lexmachine/Gopkg.toml: -------------------------------------------------------------------------------- 1 | ## "required" lists a set of packages (not projects) that must be included in 2 | ## Gopkg.lock. This list is merged with the set of packages imported by the current 3 | ## project. Use it when your project needs a package it doesn't explicitly import - 4 | ## including "main" packages. 5 | required = [] 6 | 7 | ## "ignored" lists a set of packages (not projects) that are ignored when 8 | ## dep statically analyzes source code. Ignored packages can be in this project, 9 | ## or in a dependency. 10 | ignored = [] 11 | 12 | ## Constraints are rules for how directly imported projects 13 | ## may be incorporated into the depgraph. They are respected by 14 | ## dep whether coming from the Gopkg.toml of the current project or a dependency. 15 | [[constraint]] 16 | name = "github.com/timtadh/data-structures" 17 | version = ">=0.5.2" 18 | -------------------------------------------------------------------------------- /vendor/github.com/timtadh/lexmachine/LICENSE: -------------------------------------------------------------------------------- 1 | lexmachine 2 | 3 | This library is wholly written by the authors below. Please respect all 4 | licensing terms. 5 | 6 | Copyright (c) 2014-2017 All rights reserved. Portions owned by 7 | * Tim Henderson 8 | * Case Western Reserve Univserity 9 | * Google Inc. 10 | 11 | Redistribution and use in source and binary forms, with or without 12 | modification, are permitted provided that the following conditions are met: 13 | 14 | * Redistributions of source code must retain the above copyright notice, 15 | this list of conditions and the following disclaimer. 16 | * Redistributions in binary form must reproduce the above copyright notice, 17 | this list of conditions and the following disclaimer in the documentation 18 | and/or other materials provided with the distribution. 19 | * Neither the name of the lexmachine nor the names of its contributors may 20 | be used to endorse or promote products derived from this software without 21 | specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 27 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 30 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | -------------------------------------------------------------------------------- /vendor/github.com/timtadh/lexmachine/dfa/dfa_helpers.go: -------------------------------------------------------------------------------- 1 | package dfa 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/timtadh/lexmachine/frontend" 7 | ) 8 | 9 | // LabeledAST is a post-order labeled version of the AST. The root the node will be Order[len(Order)-1]. 10 | type LabeledAST struct { 11 | Root frontend.AST // root of the AST 12 | Order []frontend.AST // post-order labeling of the all the nodes 13 | Kids [][]int // a lookup table of location for each of the nodes children 14 | Positions []int // a labeling of all the position nodes (Character/Range) in the AST. 15 | posmap map[int]int // maps an order index to a pos index. 16 | Matches []int // the index (in Positions) of all the EOS nodes 17 | nullable []bool 18 | first [][]int 19 | last [][]int 20 | follow []map[int]bool 21 | } 22 | 23 | // Label a tree and its "positions" (Character/Range nodes) in post-order 24 | // notation. 25 | func Label(ast frontend.AST) *LabeledAST { 26 | type entry struct { 27 | n frontend.AST 28 | i int 29 | kids []int 30 | } 31 | order := make([]frontend.AST, 0, 10) 32 | children := make([][]int, 0, 10) 33 | positions := make([]int, 0, 10) 34 | matches := make([]int, 0, 10) 35 | posmap := make(map[int]int) 36 | stack := make([]entry, 0, 10) 37 | stack = append(stack, entry{ast, 0, []int{}}) 38 | for len(stack) > 0 { 39 | var c entry 40 | stack, c = stack[:len(stack)-1], stack[len(stack)-1] 41 | kids := c.n.Children() 42 | for c.i < len(kids) { 43 | kid := kids[c.i] 44 | stack = append(stack, entry{c.n, c.i + 1, c.kids}) 45 | c = entry{kid, 0, []int{}} 46 | kids = c.n.Children() 47 | } 48 | oid := len(order) 49 | if len(stack) > 0 { 50 | stack[len(stack)-1].kids = append(stack[len(stack)-1].kids, oid) 51 | } 52 | order = append(order, c.n) 53 | children = append(children, c.kids) 54 | switch c.n.(type) { 55 | case *frontend.Character, *frontend.Range: 56 | posmap[oid] = len(positions) 57 | positions = append(positions, oid) 58 | case *frontend.EOS: 59 | pid := len(positions) 60 | posmap[oid] = pid 61 | positions = append(positions, oid) 62 | matches = append(matches, pid) 63 | } 64 | } 65 | return &LabeledAST{ 66 | Root: ast, 67 | Order: order, 68 | Kids: children, 69 | Positions: positions, 70 | posmap: posmap, 71 | Matches: matches, 72 | } 73 | } 74 | 75 | func (a *LabeledAST) pos(oid int) int { 76 | if pid, has := a.posmap[oid]; !has { 77 | panic("Passed a bad order id into Position (likely used a non-position node's id)") 78 | } else { 79 | return pid 80 | } 81 | } 82 | 83 | // Follow computes look up tables for each Position (leaf node) in the tree 84 | // which indicates what other Position could follow the current position in a 85 | // matching string. It also computes what positions appear first in the tree. 86 | func (a *LabeledAST) Follow() (firstOfTree []int, follow []map[int]bool) { 87 | positions := a.Positions 88 | nullable := a.MatchesEmptyString() 89 | first := a.First() 90 | last := a.Last() 91 | 92 | // get the first of the whole ast by retrieving the first for the root (len(order)-1). 93 | firstOfTree = make([]int, 0, len(first[len(a.Order)-1])) 94 | for _, p := range first[len(a.Order)-1] { 95 | firstOfTree = append(firstOfTree, p) 96 | } 97 | 98 | if a.follow != nil { 99 | return firstOfTree, a.follow 100 | } 101 | 102 | follow = make([]map[int]bool, len(positions)) 103 | for i := range follow { 104 | follow[i] = make(map[int]bool) 105 | } 106 | for i, node := range a.Order { 107 | switch n := node.(type) { 108 | case *frontend.Concat: 109 | for x := 0; x < len(n.Items)-1; x++ { 110 | j := a.Kids[i][x] 111 | kFirst := make([]int, 0, 10) 112 | for y := x + 1; y < len(n.Items); y++ { 113 | k := a.Kids[i][y] 114 | for _, p := range first[k] { 115 | kFirst = append(kFirst, p) 116 | } 117 | if !nullable[k] { 118 | break 119 | } 120 | } 121 | for _, p := range last[j] { 122 | for _, q := range kFirst { 123 | follow[p][q] = true 124 | } 125 | } 126 | } 127 | case *frontend.Star, *frontend.Plus: 128 | nFirst := make([]int, 0, 10) 129 | for _, p := range first[i] { 130 | nFirst = append(nFirst, p) 131 | } 132 | for _, p := range last[i] { 133 | for _, q := range nFirst { 134 | follow[p][q] = true 135 | } 136 | } 137 | } 138 | } 139 | 140 | a.follow = follow 141 | return firstOfTree, follow 142 | } 143 | 144 | // MatchesEmptyString computes a look up table for each node in the tree (in 145 | // post order, matching the Order member) on whether or not the subtree rooted 146 | // in each node matches the empty string. 147 | func (a *LabeledAST) MatchesEmptyString() (nullable []bool) { 148 | if a.nullable != nil { 149 | return a.nullable 150 | } 151 | nullable = make([]bool, 0, len(a.Order)) 152 | for i, node := range a.Order { 153 | switch n := node.(type) { 154 | case *frontend.EOS: 155 | nullable = append(nullable, true) 156 | case *frontend.Character: 157 | nullable = append(nullable, false) 158 | case *frontend.Range: 159 | nullable = append(nullable, false) 160 | case *frontend.Maybe: 161 | nullable = append(nullable, true) 162 | case *frontend.Plus: 163 | nullable = append(nullable, nullable[a.Kids[i][0]]) 164 | case *frontend.Star: 165 | nullable = append(nullable, true) 166 | case *frontend.Match: 167 | nullable = append(nullable, nullable[a.Kids[i][0]]) 168 | case *frontend.Alternation: 169 | nullable = append(nullable, nullable[a.Kids[i][0]] || nullable[a.Kids[i][1]]) 170 | case *frontend.AltMatch: 171 | nullable = append(nullable, nullable[a.Kids[i][0]] || nullable[a.Kids[i][1]]) 172 | case *frontend.Concat: 173 | epsilon := true 174 | for _, j := range a.Kids[i] { 175 | epsilon = epsilon && nullable[j] 176 | } 177 | nullable = append(nullable, epsilon) 178 | default: 179 | panic(fmt.Errorf("Unexpected type %T", n)) 180 | } 181 | } 182 | a.nullable = nullable 183 | return nullable 184 | } 185 | 186 | // First computes a look up table for each node in the tree (in post order, 187 | // matching the Order member) indicating for the subtree rooted at each node 188 | // which positions (leaf nodes indexes in the Positions slice) will appear at 189 | // the beginning of a string matching that subtree. 190 | func (a *LabeledAST) First() (first [][]int) { 191 | if a.first != nil { 192 | return a.first 193 | } 194 | nullable := a.MatchesEmptyString() 195 | first = make([][]int, 0, len(a.Order)) 196 | for i, node := range a.Order { 197 | switch n := node.(type) { 198 | case *frontend.EOS: 199 | first = append(first, []int{a.pos(i)}) 200 | case *frontend.Character: 201 | first = append(first, []int{a.pos(i)}) 202 | case *frontend.Range: 203 | first = append(first, []int{a.pos(i)}) 204 | case *frontend.Maybe: 205 | first = append(first, first[a.Kids[i][0]]) 206 | case *frontend.Plus: 207 | first = append(first, first[a.Kids[i][0]]) 208 | case *frontend.Star: 209 | first = append(first, first[a.Kids[i][0]]) 210 | case *frontend.Match: 211 | first = append(first, first[a.Kids[i][0]]) 212 | case *frontend.Alternation: 213 | first = append(first, append(first[a.Kids[i][0]], first[a.Kids[i][1]]...)) 214 | case *frontend.AltMatch: 215 | first = append(first, append(first[a.Kids[i][0]], first[a.Kids[i][1]]...)) 216 | case *frontend.Concat: 217 | f := make([]int, 0, len(n.Items)) 218 | for _, j := range a.Kids[i] { 219 | f = append(f, first[j]...) 220 | if !nullable[j] { 221 | break 222 | } 223 | } 224 | first = append(first, f) 225 | default: 226 | panic(fmt.Errorf("Unexpected type %T", n)) 227 | } 228 | } 229 | a.first = first 230 | return first 231 | } 232 | 233 | // Last computes a look up table for each node in the tree (in post order, 234 | // matching the Order member) indicating for the subtree rooted at each node 235 | // which positions (leaf nodes indexes in the Positions slice) will appear at 236 | // the end of a string matching that subtree. 237 | func (a *LabeledAST) Last() (last [][]int) { 238 | if a.last != nil { 239 | return a.last 240 | } 241 | nullable := a.MatchesEmptyString() 242 | last = make([][]int, 0, len(a.Order)) 243 | for i, node := range a.Order { 244 | switch n := node.(type) { 245 | case *frontend.EOS: 246 | last = append(last, []int{a.pos(i)}) 247 | case *frontend.Character: 248 | last = append(last, []int{a.pos(i)}) 249 | case *frontend.Range: 250 | last = append(last, []int{a.pos(i)}) 251 | case *frontend.Maybe: 252 | last = append(last, last[a.Kids[i][0]]) 253 | case *frontend.Plus: 254 | last = append(last, last[a.Kids[i][0]]) 255 | case *frontend.Star: 256 | last = append(last, last[a.Kids[i][0]]) 257 | case *frontend.Match: 258 | last = append(last, last[a.Kids[i][0]]) 259 | case *frontend.Alternation: 260 | last = append(last, append(last[a.Kids[i][0]], last[a.Kids[i][1]]...)) 261 | case *frontend.AltMatch: 262 | last = append(last, append(last[a.Kids[i][0]], last[a.Kids[i][1]]...)) 263 | case *frontend.Concat: 264 | l := make([]int, 0, len(n.Items)) 265 | for x := len(n.Items) - 1; x >= 0; x-- { 266 | j := a.Kids[i][x] 267 | l = append(l, last[j]...) 268 | if !nullable[j] { 269 | break 270 | } 271 | } 272 | last = append(last, l) 273 | default: 274 | panic(fmt.Errorf("Unexpected type %T", n)) 275 | } 276 | } 277 | a.last = last 278 | return last 279 | } 280 | -------------------------------------------------------------------------------- /vendor/github.com/timtadh/lexmachine/doc.go: -------------------------------------------------------------------------------- 1 | // Package lexmachine is a full lexical analysis framework for the Go 2 | // programming language. It supports a restricted but usable set of regular 3 | // expressions appropriate for writing lexers for complex programming 4 | // languages. The framework also supports sub-lexers and non-regular lexing 5 | // through an "escape hatch" which allows the users to consume any number of 6 | // further bytes after a match. So if you want to support nested C-style 7 | // comments or other paired structures you can do so at the lexical analysis 8 | // stage. 9 | // 10 | // For a tutorial see 11 | // http://hackthology.com/writing-a-lexer-in-go-with-lexmachine.html 12 | // 13 | // Example of defining a lexer 14 | // 15 | // // CreateLexer defines a lexer for the graphviz dot language. 16 | // func CreateLexer() (*lexmachine.Lexer, error) { 17 | // lexer := lexmachine.NewLexer() 18 | // 19 | // for _, lit := range Literals { 20 | // r := "\\" + strings.Join(strings.Split(lit, ""), "\\") 21 | // lexer.Add([]byte(r), token(lit)) 22 | // } 23 | // for _, name := range Keywords { 24 | // lexer.Add([]byte(strings.ToLower(name)), token(name)) 25 | // } 26 | // 27 | // lexer.Add([]byte(`//[^\n]*\n?`), token("COMMENT")) 28 | // lexer.Add([]byte(`/\*([^*]|\r|\n|(\*+([^*/]|\r|\n)))*\*+/`), token("COMMENT")) 29 | // lexer.Add([]byte(`([a-z]|[A-Z])([a-z]|[A-Z]|[0-9]|_)*`), token("ID")) 30 | // lexer.Add([]byte(`"([^\\"]|(\\.))*"`), token("ID")) 31 | // lexer.Add([]byte("( |\t|\n|\r)+"), skip) 32 | // lexer.Add([]byte(`\<`), 33 | // func(scan *lexmachine.Scanner, match *machines.Match) (interface{}, error) { 34 | // str := make([]byte, 0, 10) 35 | // str = append(str, match.Bytes...) 36 | // brackets := 1 37 | // match.EndLine = match.StartLine 38 | // match.EndColumn = match.StartColumn 39 | // for tc := scan.TC; tc < len(scan.Text); tc++ { 40 | // str = append(str, scan.Text[tc]) 41 | // match.EndColumn += 1 42 | // if scan.Text[tc] == '\n' { 43 | // match.EndLine += 1 44 | // } 45 | // if scan.Text[tc] == '<' { 46 | // brackets += 1 47 | // } else if scan.Text[tc] == '>' { 48 | // brackets -= 1 49 | // } 50 | // if brackets == 0 { 51 | // match.TC = scan.TC 52 | // scan.TC = tc + 1 53 | // match.Bytes = str 54 | // return token("ID")(scan, match) 55 | // } 56 | // } 57 | // return nil, 58 | // fmt.Errorf("unclosed HTML literal starting at %d, (%d, %d)", 59 | // match.TC, match.StartLine, match.StartColumn) 60 | // }, 61 | // ) 62 | // 63 | // err := lexer.Compile() 64 | // if err != nil { 65 | // return nil, err 66 | // } 67 | // return lexer, nil 68 | // } 69 | // 70 | // func token(name string) lex.Action { 71 | // return func(s *lex.Scanner, m *machines.Match) (interface{}, error) { 72 | // return s.Token(TokenIds[name], string(m.Bytes), m), nil 73 | // } 74 | // } 75 | // 76 | // Example of using a lexer 77 | // 78 | // func ExampleLex() error { 79 | // lexer, err := CreateLexer() 80 | // if err != nil { 81 | // return err 82 | // } 83 | // scanner, err := lexer.Scanner([]byte(`digraph { 84 | // rankdir=LR; 85 | // a [label="a" shape=box]; 86 | // c [