aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/aws/aws-sdk-go/internal/ini
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/aws/aws-sdk-go/internal/ini')
-rw-r--r--vendor/github.com/aws/aws-sdk-go/internal/ini/ast.go120
-rw-r--r--vendor/github.com/aws/aws-sdk-go/internal/ini/comma_token.go11
-rw-r--r--vendor/github.com/aws/aws-sdk-go/internal/ini/comment_token.go35
-rw-r--r--vendor/github.com/aws/aws-sdk-go/internal/ini/doc.go29
-rw-r--r--vendor/github.com/aws/aws-sdk-go/internal/ini/empty_token.go4
-rw-r--r--vendor/github.com/aws/aws-sdk-go/internal/ini/expression.go24
-rw-r--r--vendor/github.com/aws/aws-sdk-go/internal/ini/fuzz.go17
-rw-r--r--vendor/github.com/aws/aws-sdk-go/internal/ini/ini.go51
-rw-r--r--vendor/github.com/aws/aws-sdk-go/internal/ini/ini_lexer.go165
-rw-r--r--vendor/github.com/aws/aws-sdk-go/internal/ini/ini_parser.go347
-rw-r--r--vendor/github.com/aws/aws-sdk-go/internal/ini/literal_tokens.go324
-rw-r--r--vendor/github.com/aws/aws-sdk-go/internal/ini/newline_token.go30
-rw-r--r--vendor/github.com/aws/aws-sdk-go/internal/ini/number_helper.go152
-rw-r--r--vendor/github.com/aws/aws-sdk-go/internal/ini/op_tokens.go39
-rw-r--r--vendor/github.com/aws/aws-sdk-go/internal/ini/parse_error.go43
-rw-r--r--vendor/github.com/aws/aws-sdk-go/internal/ini/parse_stack.go60
-rw-r--r--vendor/github.com/aws/aws-sdk-go/internal/ini/sep_tokens.go41
-rw-r--r--vendor/github.com/aws/aws-sdk-go/internal/ini/skipper.go45
-rw-r--r--vendor/github.com/aws/aws-sdk-go/internal/ini/statement.go35
-rw-r--r--vendor/github.com/aws/aws-sdk-go/internal/ini/value_util.go284
-rw-r--r--vendor/github.com/aws/aws-sdk-go/internal/ini/visitor.go166
-rw-r--r--vendor/github.com/aws/aws-sdk-go/internal/ini/walker.go25
-rw-r--r--vendor/github.com/aws/aws-sdk-go/internal/ini/ws_token.go24
23 files changed, 2071 insertions, 0 deletions
diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/ast.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/ast.go
new file mode 100644
index 0000000..e83a998
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/ast.go
@@ -0,0 +1,120 @@
1package ini
2
3// ASTKind represents different states in the parse table
4// and the type of AST that is being constructed
5type ASTKind int
6
7// ASTKind* is used in the parse table to transition between
8// the different states
9const (
10 ASTKindNone = ASTKind(iota)
11 ASTKindStart
12 ASTKindExpr
13 ASTKindEqualExpr
14 ASTKindStatement
15 ASTKindSkipStatement
16 ASTKindExprStatement
17 ASTKindSectionStatement
18 ASTKindNestedSectionStatement
19 ASTKindCompletedNestedSectionStatement
20 ASTKindCommentStatement
21 ASTKindCompletedSectionStatement
22)
23
24func (k ASTKind) String() string {
25 switch k {
26 case ASTKindNone:
27 return "none"
28 case ASTKindStart:
29 return "start"
30 case ASTKindExpr:
31 return "expr"
32 case ASTKindStatement:
33 return "stmt"
34 case ASTKindSectionStatement:
35 return "section_stmt"
36 case ASTKindExprStatement:
37 return "expr_stmt"
38 case ASTKindCommentStatement:
39 return "comment"
40 case ASTKindNestedSectionStatement:
41 return "nested_section_stmt"
42 case ASTKindCompletedSectionStatement:
43 return "completed_stmt"
44 case ASTKindSkipStatement:
45 return "skip"
46 default:
47 return ""
48 }
49}
50
51// AST interface allows us to determine what kind of node we
52// are on and casting may not need to be necessary.
53//
54// The root is always the first node in Children
55type AST struct {
56 Kind ASTKind
57 Root Token
58 RootToken bool
59 Children []AST
60}
61
62func newAST(kind ASTKind, root AST, children ...AST) AST {
63 return AST{
64 Kind: kind,
65 Children: append([]AST{root}, children...),
66 }
67}
68
69func newASTWithRootToken(kind ASTKind, root Token, children ...AST) AST {
70 return AST{
71 Kind: kind,
72 Root: root,
73 RootToken: true,
74 Children: children,
75 }
76}
77
78// AppendChild will append to the list of children an AST has.
79func (a *AST) AppendChild(child AST) {
80 a.Children = append(a.Children, child)
81}
82
83// GetRoot will return the root AST which can be the first entry
84// in the children list or a token.
85func (a *AST) GetRoot() AST {
86 if a.RootToken {
87 return *a
88 }
89
90 if len(a.Children) == 0 {
91 return AST{}
92 }
93
94 return a.Children[0]
95}
96
97// GetChildren will return the current AST's list of children
98func (a *AST) GetChildren() []AST {
99 if len(a.Children) == 0 {
100 return []AST{}
101 }
102
103 if a.RootToken {
104 return a.Children
105 }
106
107 return a.Children[1:]
108}
109
110// SetChildren will set and override all children of the AST.
111func (a *AST) SetChildren(children []AST) {
112 if a.RootToken {
113 a.Children = children
114 } else {
115 a.Children = append(a.Children[:1], children...)
116 }
117}
118
119// Start is used to indicate the starting state of the parse table.
120var Start = newAST(ASTKindStart, AST{})
diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/comma_token.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/comma_token.go
new file mode 100644
index 0000000..0895d53
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/comma_token.go
@@ -0,0 +1,11 @@
1package ini
2
3var commaRunes = []rune(",")
4
5func isComma(b rune) bool {
6 return b == ','
7}
8
9func newCommaToken() Token {
10 return newToken(TokenComma, commaRunes, NoneType)
11}
diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/comment_token.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/comment_token.go
new file mode 100644
index 0000000..0b76999
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/comment_token.go
@@ -0,0 +1,35 @@
1package ini
2
3// isComment will return whether or not the next byte(s) is a
4// comment.
5func isComment(b []rune) bool {
6 if len(b) == 0 {
7 return false
8 }
9
10 switch b[0] {
11 case ';':
12 return true
13 case '#':
14 return true
15 }
16
17 return false
18}
19
20// newCommentToken will create a comment token and
21// return how many bytes were read.
22func newCommentToken(b []rune) (Token, int, error) {
23 i := 0
24 for ; i < len(b); i++ {
25 if b[i] == '\n' {
26 break
27 }
28
29 if len(b)-i > 2 && b[i] == '\r' && b[i+1] == '\n' {
30 break
31 }
32 }
33
34 return newToken(TokenComment, b[:i], NoneType), i, nil
35}
diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/doc.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/doc.go
new file mode 100644
index 0000000..25ce0fe
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/doc.go
@@ -0,0 +1,29 @@
1// Package ini is an LL(1) parser for configuration files.
2//
3// Example:
4// sections, err := ini.OpenFile("/path/to/file")
5// if err != nil {
6// panic(err)
7// }
8//
9// profile := "foo"
10// section, ok := sections.GetSection(profile)
11// if !ok {
12// fmt.Printf("section %q could not be found", profile)
13// }
14//
15// Below is the BNF that describes this parser
16// Grammar:
17// stmt -> value stmt'
18// stmt' -> epsilon | op stmt
19// value -> number | string | boolean | quoted_string
20//
21// section -> [ section'
22// section' -> value section_close
23// section_close -> ]
24//
25// SkipState will skip (NL WS)+
26//
27// comment -> # comment' | ; comment'
28// comment' -> epsilon | value
29package ini
diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/empty_token.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/empty_token.go
new file mode 100644
index 0000000..04345a5
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/empty_token.go
@@ -0,0 +1,4 @@
1package ini
2
3// emptyToken is used to satisfy the Token interface
4var emptyToken = newToken(TokenNone, []rune{}, NoneType)
diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/expression.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/expression.go
new file mode 100644
index 0000000..91ba2a5
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/expression.go
@@ -0,0 +1,24 @@
1package ini
2
3// newExpression will return an expression AST.
4// Expr represents an expression
5//
6// grammar:
7// expr -> string | number
8func newExpression(tok Token) AST {
9 return newASTWithRootToken(ASTKindExpr, tok)
10}
11
12func newEqualExpr(left AST, tok Token) AST {
13 return newASTWithRootToken(ASTKindEqualExpr, tok, left)
14}
15
16// EqualExprKey will return a LHS value in the equal expr
17func EqualExprKey(ast AST) string {
18 children := ast.GetChildren()
19 if len(children) == 0 || ast.Kind != ASTKindEqualExpr {
20 return ""
21 }
22
23 return string(children[0].Root.Raw())
24}
diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/fuzz.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/fuzz.go
new file mode 100644
index 0000000..8d462f7
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/fuzz.go
@@ -0,0 +1,17 @@
1// +build gofuzz
2
3package ini
4
5import (
6 "bytes"
7)
8
9func Fuzz(data []byte) int {
10 b := bytes.NewReader(data)
11
12 if _, err := Parse(b); err != nil {
13 return 0
14 }
15
16 return 1
17}
diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/ini.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/ini.go
new file mode 100644
index 0000000..3b0ca7a
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/ini.go
@@ -0,0 +1,51 @@
1package ini
2
3import (
4 "io"
5 "os"
6
7 "github.com/aws/aws-sdk-go/aws/awserr"
8)
9
10// OpenFile takes a path to a given file, and will open and parse
11// that file.
12func OpenFile(path string) (Sections, error) {
13 f, err := os.Open(path)
14 if err != nil {
15 return Sections{}, awserr.New(ErrCodeUnableToReadFile, "unable to open file", err)
16 }
17 defer f.Close()
18
19 return Parse(f)
20}
21
22// Parse will parse the given file using the shared config
23// visitor.
24func Parse(f io.Reader) (Sections, error) {
25 tree, err := ParseAST(f)
26 if err != nil {
27 return Sections{}, err
28 }
29
30 v := NewDefaultVisitor()
31 if err = Walk(tree, v); err != nil {
32 return Sections{}, err
33 }
34
35 return v.Sections, nil
36}
37
38// ParseBytes will parse the given bytes and return the parsed sections.
39func ParseBytes(b []byte) (Sections, error) {
40 tree, err := ParseASTBytes(b)
41 if err != nil {
42 return Sections{}, err
43 }
44
45 v := NewDefaultVisitor()
46 if err = Walk(tree, v); err != nil {
47 return Sections{}, err
48 }
49
50 return v.Sections, nil
51}
diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/ini_lexer.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/ini_lexer.go
new file mode 100644
index 0000000..582c024
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/ini_lexer.go
@@ -0,0 +1,165 @@
1package ini
2
3import (
4 "bytes"
5 "io"
6 "io/ioutil"
7
8 "github.com/aws/aws-sdk-go/aws/awserr"
9)
10
11const (
12 // ErrCodeUnableToReadFile is used when a file is failed to be
13 // opened or read from.
14 ErrCodeUnableToReadFile = "FailedRead"
15)
16
17// TokenType represents the various different tokens types
18type TokenType int
19
20func (t TokenType) String() string {
21 switch t {
22 case TokenNone:
23 return "none"
24 case TokenLit:
25 return "literal"
26 case TokenSep:
27 return "sep"
28 case TokenOp:
29 return "op"
30 case TokenWS:
31 return "ws"
32 case TokenNL:
33 return "newline"
34 case TokenComment:
35 return "comment"
36 case TokenComma:
37 return "comma"
38 default:
39 return ""
40 }
41}
42
43// TokenType enums
44const (
45 TokenNone = TokenType(iota)
46 TokenLit
47 TokenSep
48 TokenComma
49 TokenOp
50 TokenWS
51 TokenNL
52 TokenComment
53)
54
55type iniLexer struct{}
56
57// Tokenize will return a list of tokens during lexical analysis of the
58// io.Reader.
59func (l *iniLexer) Tokenize(r io.Reader) ([]Token, error) {
60 b, err := ioutil.ReadAll(r)
61 if err != nil {
62 return nil, awserr.New(ErrCodeUnableToReadFile, "unable to read file", err)
63 }
64
65 return l.tokenize(b)
66}
67
68func (l *iniLexer) tokenize(b []byte) ([]Token, error) {
69 runes := bytes.Runes(b)
70 var err error
71 n := 0
72 tokenAmount := countTokens(runes)
73 tokens := make([]Token, tokenAmount)
74 count := 0
75
76 for len(runes) > 0 && count < tokenAmount {
77 switch {
78 case isWhitespace(runes[0]):
79 tokens[count], n, err = newWSToken(runes)
80 case isComma(runes[0]):
81 tokens[count], n = newCommaToken(), 1
82 case isComment(runes):
83 tokens[count], n, err = newCommentToken(runes)
84 case isNewline(runes):
85 tokens[count], n, err = newNewlineToken(runes)
86 case isSep(runes):
87 tokens[count], n, err = newSepToken(runes)
88 case isOp(runes):
89 tokens[count], n, err = newOpToken(runes)
90 default:
91 tokens[count], n, err = newLitToken(runes)
92 }
93
94 if err != nil {
95 return nil, err
96 }
97
98 count++
99
100 runes = runes[n:]
101 }
102
103 return tokens[:count], nil
104}
105
106func countTokens(runes []rune) int {
107 count, n := 0, 0
108 var err error
109
110 for len(runes) > 0 {
111 switch {
112 case isWhitespace(runes[0]):
113 _, n, err = newWSToken(runes)
114 case isComma(runes[0]):
115 _, n = newCommaToken(), 1
116 case isComment(runes):
117 _, n, err = newCommentToken(runes)
118 case isNewline(runes):
119 _, n, err = newNewlineToken(runes)
120 case isSep(runes):
121 _, n, err = newSepToken(runes)
122 case isOp(runes):
123 _, n, err = newOpToken(runes)
124 default:
125 _, n, err = newLitToken(runes)
126 }
127
128 if err != nil {
129 return 0
130 }
131
132 count++
133 runes = runes[n:]
134 }
135
136 return count + 1
137}
138
139// Token indicates a metadata about a given value.
140type Token struct {
141 t TokenType
142 ValueType ValueType
143 base int
144 raw []rune
145}
146
147var emptyValue = Value{}
148
149func newToken(t TokenType, raw []rune, v ValueType) Token {
150 return Token{
151 t: t,
152 raw: raw,
153 ValueType: v,
154 }
155}
156
157// Raw return the raw runes that were consumed
158func (tok Token) Raw() []rune {
159 return tok.raw
160}
161
162// Type returns the token type
163func (tok Token) Type() TokenType {
164 return tok.t
165}
diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/ini_parser.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/ini_parser.go
new file mode 100644
index 0000000..f997033
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/ini_parser.go
@@ -0,0 +1,347 @@
1package ini
2
3import (
4 "fmt"
5 "io"
6)
7
8// State enums for the parse table
9const (
10 InvalidState = iota
11 // stmt -> value stmt'
12 StatementState
13 // stmt' -> MarkComplete | op stmt
14 StatementPrimeState
15 // value -> number | string | boolean | quoted_string
16 ValueState
17 // section -> [ section'
18 OpenScopeState
19 // section' -> value section_close
20 SectionState
21 // section_close -> ]
22 CloseScopeState
23 // SkipState will skip (NL WS)+
24 SkipState
25 // SkipTokenState will skip any token and push the previous
26 // state onto the stack.
27 SkipTokenState
28 // comment -> # comment' | ; comment'
29 // comment' -> MarkComplete | value
30 CommentState
31 // MarkComplete state will complete statements and move that
32 // to the completed AST list
33 MarkCompleteState
34 // TerminalState signifies that the tokens have been fully parsed
35 TerminalState
36)
37
38// parseTable is a state machine to dictate the grammar above.
39var parseTable = map[ASTKind]map[TokenType]int{
40 ASTKindStart: map[TokenType]int{
41 TokenLit: StatementState,
42 TokenSep: OpenScopeState,
43 TokenWS: SkipTokenState,
44 TokenNL: SkipTokenState,
45 TokenComment: CommentState,
46 TokenNone: TerminalState,
47 },
48 ASTKindCommentStatement: map[TokenType]int{
49 TokenLit: StatementState,
50 TokenSep: OpenScopeState,
51 TokenWS: SkipTokenState,
52 TokenNL: SkipTokenState,
53 TokenComment: CommentState,
54 TokenNone: MarkCompleteState,
55 },
56 ASTKindExpr: map[TokenType]int{
57 TokenOp: StatementPrimeState,
58 TokenLit: ValueState,
59 TokenSep: OpenScopeState,
60 TokenWS: ValueState,
61 TokenNL: SkipState,
62 TokenComment: CommentState,
63 TokenNone: MarkCompleteState,
64 },
65 ASTKindEqualExpr: map[TokenType]int{
66 TokenLit: ValueState,
67 TokenWS: SkipTokenState,
68 TokenNL: SkipState,
69 },
70 ASTKindStatement: map[TokenType]int{
71 TokenLit: SectionState,
72 TokenSep: CloseScopeState,
73 TokenWS: SkipTokenState,
74 TokenNL: SkipTokenState,
75 TokenComment: CommentState,
76 TokenNone: MarkCompleteState,
77 },
78 ASTKindExprStatement: map[TokenType]int{
79 TokenLit: ValueState,
80 TokenSep: OpenScopeState,
81 TokenOp: ValueState,
82 TokenWS: ValueState,
83 TokenNL: MarkCompleteState,
84 TokenComment: CommentState,
85 TokenNone: TerminalState,
86 TokenComma: SkipState,
87 },
88 ASTKindSectionStatement: map[TokenType]int{
89 TokenLit: SectionState,
90 TokenOp: SectionState,
91 TokenSep: CloseScopeState,
92 TokenWS: SectionState,
93 TokenNL: SkipTokenState,
94 },
95 ASTKindCompletedSectionStatement: map[TokenType]int{
96 TokenWS: SkipTokenState,
97 TokenNL: SkipTokenState,
98 TokenLit: StatementState,
99 TokenSep: OpenScopeState,
100 TokenComment: CommentState,
101 TokenNone: MarkCompleteState,
102 },
103 ASTKindSkipStatement: map[TokenType]int{
104 TokenLit: StatementState,
105 TokenSep: OpenScopeState,
106 TokenWS: SkipTokenState,
107 TokenNL: SkipTokenState,
108 TokenComment: CommentState,
109 TokenNone: TerminalState,
110 },
111}
112
113// ParseAST will parse input from an io.Reader using
114// an LL(1) parser.
115func ParseAST(r io.Reader) ([]AST, error) {
116 lexer := iniLexer{}
117 tokens, err := lexer.Tokenize(r)
118 if err != nil {
119 return []AST{}, err
120 }
121
122 return parse(tokens)
123}
124
125// ParseASTBytes will parse input from a byte slice using
126// an LL(1) parser.
127func ParseASTBytes(b []byte) ([]AST, error) {
128 lexer := iniLexer{}
129 tokens, err := lexer.tokenize(b)
130 if err != nil {
131 return []AST{}, err
132 }
133
134 return parse(tokens)
135}
136
137func parse(tokens []Token) ([]AST, error) {
138 start := Start
139 stack := newParseStack(3, len(tokens))
140
141 stack.Push(start)
142 s := newSkipper()
143
144loop:
145 for stack.Len() > 0 {
146 k := stack.Pop()
147
148 var tok Token
149 if len(tokens) == 0 {
150 // this occurs when all the tokens have been processed
151 // but reduction of what's left on the stack needs to
152 // occur.
153 tok = emptyToken
154 } else {
155 tok = tokens[0]
156 }
157
158 step := parseTable[k.Kind][tok.Type()]
159 if s.ShouldSkip(tok) {
160 // being in a skip state with no tokens will break out of
161 // the parse loop since there is nothing left to process.
162 if len(tokens) == 0 {
163 break loop
164 }
165
166 step = SkipTokenState
167 }
168
169 switch step {
170 case TerminalState:
171 // Finished parsing. Push what should be the last
172 // statement to the stack. If there is anything left
173 // on the stack, an error in parsing has occurred.
174 if k.Kind != ASTKindStart {
175 stack.MarkComplete(k)
176 }
177 break loop
178 case SkipTokenState:
179 // When skipping a token, the previous state was popped off the stack.
180 // To maintain the correct state, the previous state will be pushed
181 // onto the stack.
182 stack.Push(k)
183 case StatementState:
184 if k.Kind != ASTKindStart {
185 stack.MarkComplete(k)
186 }
187 expr := newExpression(tok)
188 stack.Push(expr)
189 case StatementPrimeState:
190 if tok.Type() != TokenOp {
191 stack.MarkComplete(k)
192 continue
193 }
194
195 if k.Kind != ASTKindExpr {
196 return nil, NewParseError(
197 fmt.Sprintf("invalid expression: expected Expr type, but found %T type", k),
198 )
199 }
200
201 k = trimSpaces(k)
202 expr := newEqualExpr(k, tok)
203 stack.Push(expr)
204 case ValueState:
205 // ValueState requires the previous state to either be an equal expression
206 // or an expression statement.
207 //
208 // This grammar occurs when the RHS is a number, word, or quoted string.
209 // equal_expr -> lit op equal_expr'
210 // equal_expr' -> number | string | quoted_string
211 // quoted_string -> " quoted_string'
212 // quoted_string' -> string quoted_string_end
213 // quoted_string_end -> "
214 //
215 // otherwise
216 // expr_stmt -> equal_expr (expr_stmt')*
217 // expr_stmt' -> ws S | op S | MarkComplete
218 // S -> equal_expr' expr_stmt'
219 switch k.Kind {
220 case ASTKindEqualExpr:
221 // assiging a value to some key
222 k.AppendChild(newExpression(tok))
223 stack.Push(newExprStatement(k))
224 case ASTKindExpr:
225 k.Root.raw = append(k.Root.raw, tok.Raw()...)
226 stack.Push(k)
227 case ASTKindExprStatement:
228 root := k.GetRoot()
229 children := root.GetChildren()
230 if len(children) == 0 {
231 return nil, NewParseError(
232 fmt.Sprintf("invalid expression: AST contains no children %s", k.Kind),
233 )
234 }
235
236 rhs := children[len(children)-1]
237
238 if rhs.Root.ValueType != QuotedStringType {
239 rhs.Root.ValueType = StringType
240 rhs.Root.raw = append(rhs.Root.raw, tok.Raw()...)
241
242 }
243
244 children[len(children)-1] = rhs
245 k.SetChildren(children)
246
247 stack.Push(k)
248 }
249 case OpenScopeState:
250 if !runeCompare(tok.Raw(), openBrace) {
251 return nil, NewParseError("expected '['")
252 }
253
254 stmt := newStatement()
255 stack.Push(stmt)
256 case CloseScopeState:
257 if !runeCompare(tok.Raw(), closeBrace) {
258 return nil, NewParseError("expected ']'")
259 }
260
261 k = trimSpaces(k)
262 stack.Push(newCompletedSectionStatement(k))
263 case SectionState:
264 var stmt AST
265
266 switch k.Kind {
267 case ASTKindStatement:
268 // If there are multiple literals inside of a scope declaration,
269 // then the current token's raw value will be appended to the Name.
270 //
271 // This handles cases like [ profile default ]
272 //
273 // k will represent a SectionStatement with the children representing
274 // the label of the section
275 stmt = newSectionStatement(tok)
276 case ASTKindSectionStatement:
277 k.Root.raw = append(k.Root.raw, tok.Raw()...)
278 stmt = k
279 default:
280 return nil, NewParseError(
281 fmt.Sprintf("invalid statement: expected statement: %v", k.Kind),
282 )
283 }
284
285 stack.Push(stmt)
286 case MarkCompleteState:
287 if k.Kind != ASTKindStart {
288 stack.MarkComplete(k)
289 }
290
291 if stack.Len() == 0 {
292 stack.Push(start)
293 }
294 case SkipState:
295 stack.Push(newSkipStatement(k))
296 s.Skip()
297 case CommentState:
298 if k.Kind == ASTKindStart {
299 stack.Push(k)
300 } else {
301 stack.MarkComplete(k)
302 }
303
304 stmt := newCommentStatement(tok)
305 stack.Push(stmt)
306 default:
307 return nil, NewParseError(fmt.Sprintf("invalid state with ASTKind %v and TokenType %v", k, tok))
308 }
309
310 if len(tokens) > 0 {
311 tokens = tokens[1:]
312 }
313 }
314
315 // this occurs when a statement has not been completed
316 if stack.top > 1 {
317 return nil, NewParseError(fmt.Sprintf("incomplete expression: %v", stack.container))
318 }
319
320 // returns a sublist which excludes the start symbol
321 return stack.List(), nil
322}
323
324// trimSpaces will trim spaces on the left and right hand side of
325// the literal.
326func trimSpaces(k AST) AST {
327 // trim left hand side of spaces
328 for i := 0; i < len(k.Root.raw); i++ {
329 if !isWhitespace(k.Root.raw[i]) {
330 break
331 }
332
333 k.Root.raw = k.Root.raw[1:]
334 i--
335 }
336
337 // trim right hand side of spaces
338 for i := len(k.Root.raw) - 1; i >= 0; i-- {
339 if !isWhitespace(k.Root.raw[i]) {
340 break
341 }
342
343 k.Root.raw = k.Root.raw[:len(k.Root.raw)-1]
344 }
345
346 return k
347}
diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/literal_tokens.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/literal_tokens.go
new file mode 100644
index 0000000..24df543
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/literal_tokens.go
@@ -0,0 +1,324 @@
1package ini
2
3import (
4 "fmt"
5 "strconv"
6 "strings"
7)
8
9var (
10 runesTrue = []rune("true")
11 runesFalse = []rune("false")
12)
13
14var literalValues = [][]rune{
15 runesTrue,
16 runesFalse,
17}
18
19func isBoolValue(b []rune) bool {
20 for _, lv := range literalValues {
21 if isLitValue(lv, b) {
22 return true
23 }
24 }
25 return false
26}
27
28func isLitValue(want, have []rune) bool {
29 if len(have) < len(want) {
30 return false
31 }
32
33 for i := 0; i < len(want); i++ {
34 if want[i] != have[i] {
35 return false
36 }
37 }
38
39 return true
40}
41
42// isNumberValue will return whether not the leading characters in
43// a byte slice is a number. A number is delimited by whitespace or
44// the newline token.
45//
46// A number is defined to be in a binary, octal, decimal (int | float), hex format,
47// or in scientific notation.
48func isNumberValue(b []rune) bool {
49 negativeIndex := 0
50 helper := numberHelper{}
51 needDigit := false
52
53 for i := 0; i < len(b); i++ {
54 negativeIndex++
55
56 switch b[i] {
57 case '-':
58 if helper.IsNegative() || negativeIndex != 1 {
59 return false
60 }
61 helper.Determine(b[i])
62 needDigit = true
63 continue
64 case 'e', 'E':
65 if err := helper.Determine(b[i]); err != nil {
66 return false
67 }
68 negativeIndex = 0
69 needDigit = true
70 continue
71 case 'b':
72 if helper.numberFormat == hex {
73 break
74 }
75 fallthrough
76 case 'o', 'x':
77 needDigit = true
78 if i == 0 {
79 return false
80 }
81
82 fallthrough
83 case '.':
84 if err := helper.Determine(b[i]); err != nil {
85 return false
86 }
87 needDigit = true
88 continue
89 }
90
91 if i > 0 && (isNewline(b[i:]) || isWhitespace(b[i])) {
92 return !needDigit
93 }
94
95 if !helper.CorrectByte(b[i]) {
96 return false
97 }
98 needDigit = false
99 }
100
101 return !needDigit
102}
103
104func isValid(b []rune) (bool, int, error) {
105 if len(b) == 0 {
106 // TODO: should probably return an error
107 return false, 0, nil
108 }
109
110 return isValidRune(b[0]), 1, nil
111}
112
113func isValidRune(r rune) bool {
114 return r != ':' && r != '=' && r != '[' && r != ']' && r != ' ' && r != '\n'
115}
116
117// ValueType is an enum that will signify what type
118// the Value is
119type ValueType int
120
121func (v ValueType) String() string {
122 switch v {
123 case NoneType:
124 return "NONE"
125 case DecimalType:
126 return "FLOAT"
127 case IntegerType:
128 return "INT"
129 case StringType:
130 return "STRING"
131 case BoolType:
132 return "BOOL"
133 }
134
135 return ""
136}
137
138// ValueType enums
139const (
140 NoneType = ValueType(iota)
141 DecimalType
142 IntegerType
143 StringType
144 QuotedStringType
145 BoolType
146)
147
148// Value is a union container
149type Value struct {
150 Type ValueType
151 raw []rune
152
153 integer int64
154 decimal float64
155 boolean bool
156 str string
157}
158
159func newValue(t ValueType, base int, raw []rune) (Value, error) {
160 v := Value{
161 Type: t,
162 raw: raw,
163 }
164 var err error
165
166 switch t {
167 case DecimalType:
168 v.decimal, err = strconv.ParseFloat(string(raw), 64)
169 case IntegerType:
170 if base != 10 {
171 raw = raw[2:]
172 }
173
174 v.integer, err = strconv.ParseInt(string(raw), base, 64)
175 case StringType:
176 v.str = string(raw)
177 case QuotedStringType:
178 v.str = string(raw[1 : len(raw)-1])
179 case BoolType:
180 v.boolean = runeCompare(v.raw, runesTrue)
181 }
182
183 // issue 2253
184 //
185 // if the value trying to be parsed is too large, then we will use
186 // the 'StringType' and raw value instead.
187 if nerr, ok := err.(*strconv.NumError); ok && nerr.Err == strconv.ErrRange {
188 v.Type = StringType
189 v.str = string(raw)
190 err = nil
191 }
192
193 return v, err
194}
195
196// Append will append values and change the type to a string
197// type.
198func (v *Value) Append(tok Token) {
199 r := tok.Raw()
200 if v.Type != QuotedStringType {
201 v.Type = StringType
202 r = tok.raw[1 : len(tok.raw)-1]
203 }
204 if tok.Type() != TokenLit {
205 v.raw = append(v.raw, tok.Raw()...)
206 } else {
207 v.raw = append(v.raw, r...)
208 }
209}
210
211func (v Value) String() string {
212 switch v.Type {
213 case DecimalType:
214 return fmt.Sprintf("decimal: %f", v.decimal)
215 case IntegerType:
216 return fmt.Sprintf("integer: %d", v.integer)
217 case StringType:
218 return fmt.Sprintf("string: %s", string(v.raw))
219 case QuotedStringType:
220 return fmt.Sprintf("quoted string: %s", string(v.raw))
221 case BoolType:
222 return fmt.Sprintf("bool: %t", v.boolean)
223 default:
224 return "union not set"
225 }
226}
227
228func newLitToken(b []rune) (Token, int, error) {
229 n := 0
230 var err error
231
232 token := Token{}
233 if b[0] == '"' {
234 n, err = getStringValue(b)
235 if err != nil {
236 return token, n, err
237 }
238
239 token = newToken(TokenLit, b[:n], QuotedStringType)
240 } else if isNumberValue(b) {
241 var base int
242 base, n, err = getNumericalValue(b)
243 if err != nil {
244 return token, 0, err
245 }
246
247 value := b[:n]
248 vType := IntegerType
249 if contains(value, '.') || hasExponent(value) {
250 vType = DecimalType
251 }
252 token = newToken(TokenLit, value, vType)
253 token.base = base
254 } else if isBoolValue(b) {
255 n, err = getBoolValue(b)
256
257 token = newToken(TokenLit, b[:n], BoolType)
258 } else {
259 n, err = getValue(b)
260 token = newToken(TokenLit, b[:n], StringType)
261 }
262
263 return token, n, err
264}
265
266// IntValue returns an integer value
267func (v Value) IntValue() int64 {
268 return v.integer
269}
270
271// FloatValue returns a float value
272func (v Value) FloatValue() float64 {
273 return v.decimal
274}
275
276// BoolValue returns a bool value
277func (v Value) BoolValue() bool {
278 return v.boolean
279}
280
281func isTrimmable(r rune) bool {
282 switch r {
283 case '\n', ' ':
284 return true
285 }
286 return false
287}
288
289// StringValue returns the string value
290func (v Value) StringValue() string {
291 switch v.Type {
292 case StringType:
293 return strings.TrimFunc(string(v.raw), isTrimmable)
294 case QuotedStringType:
295 // preserve all characters in the quotes
296 return string(removeEscapedCharacters(v.raw[1 : len(v.raw)-1]))
297 default:
298 return strings.TrimFunc(string(v.raw), isTrimmable)
299 }
300}
301
302func contains(runes []rune, c rune) bool {
303 for i := 0; i < len(runes); i++ {
304 if runes[i] == c {
305 return true
306 }
307 }
308
309 return false
310}
311
312func runeCompare(v1 []rune, v2 []rune) bool {
313 if len(v1) != len(v2) {
314 return false
315 }
316
317 for i := 0; i < len(v1); i++ {
318 if v1[i] != v2[i] {
319 return false
320 }
321 }
322
323 return true
324}
diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/newline_token.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/newline_token.go
new file mode 100644
index 0000000..e52ac39
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/newline_token.go
@@ -0,0 +1,30 @@
1package ini
2
3func isNewline(b []rune) bool {
4 if len(b) == 0 {
5 return false
6 }
7
8 if b[0] == '\n' {
9 return true
10 }
11
12 if len(b) < 2 {
13 return false
14 }
15
16 return b[0] == '\r' && b[1] == '\n'
17}
18
19func newNewlineToken(b []rune) (Token, int, error) {
20 i := 1
21 if b[0] == '\r' && isNewline(b[1:]) {
22 i++
23 }
24
25 if !isNewline([]rune(b[:i])) {
26 return emptyToken, 0, NewParseError("invalid new line token")
27 }
28
29 return newToken(TokenNL, b[:i], NoneType), i, nil
30}
diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/number_helper.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/number_helper.go
new file mode 100644
index 0000000..a45c0bc
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/number_helper.go
@@ -0,0 +1,152 @@
1package ini
2
3import (
4 "bytes"
5 "fmt"
6 "strconv"
7)
8
9const (
10 none = numberFormat(iota)
11 binary
12 octal
13 decimal
14 hex
15 exponent
16)
17
18type numberFormat int
19
20// numberHelper is used to dictate what format a number is in
21// and what to do for negative values. Since -1e-4 is a valid
22// number, we cannot just simply check for duplicate negatives.
23type numberHelper struct {
24 numberFormat numberFormat
25
26 negative bool
27 negativeExponent bool
28}
29
30func (b numberHelper) Exists() bool {
31 return b.numberFormat != none
32}
33
34func (b numberHelper) IsNegative() bool {
35 return b.negative || b.negativeExponent
36}
37
38func (b *numberHelper) Determine(c rune) error {
39 if b.Exists() {
40 return NewParseError(fmt.Sprintf("multiple number formats: 0%v", string(c)))
41 }
42
43 switch c {
44 case 'b':
45 b.numberFormat = binary
46 case 'o':
47 b.numberFormat = octal
48 case 'x':
49 b.numberFormat = hex
50 case 'e', 'E':
51 b.numberFormat = exponent
52 case '-':
53 if b.numberFormat != exponent {
54 b.negative = true
55 } else {
56 b.negativeExponent = true
57 }
58 case '.':
59 b.numberFormat = decimal
60 default:
61 return NewParseError(fmt.Sprintf("invalid number character: %v", string(c)))
62 }
63
64 return nil
65}
66
67func (b numberHelper) CorrectByte(c rune) bool {
68 switch {
69 case b.numberFormat == binary:
70 if !isBinaryByte(c) {
71 return false
72 }
73 case b.numberFormat == octal:
74 if !isOctalByte(c) {
75 return false
76 }
77 case b.numberFormat == hex:
78 if !isHexByte(c) {
79 return false
80 }
81 case b.numberFormat == decimal:
82 if !isDigit(c) {
83 return false
84 }
85 case b.numberFormat == exponent:
86 if !isDigit(c) {
87 return false
88 }
89 case b.negativeExponent:
90 if !isDigit(c) {
91 return false
92 }
93 case b.negative:
94 if !isDigit(c) {
95 return false
96 }
97 default:
98 if !isDigit(c) {
99 return false
100 }
101 }
102
103 return true
104}
105
106func (b numberHelper) Base() int {
107 switch b.numberFormat {
108 case binary:
109 return 2
110 case octal:
111 return 8
112 case hex:
113 return 16
114 default:
115 return 10
116 }
117}
118
119func (b numberHelper) String() string {
120 buf := bytes.Buffer{}
121 i := 0
122
123 switch b.numberFormat {
124 case binary:
125 i++
126 buf.WriteString(strconv.Itoa(i) + ": binary format\n")
127 case octal:
128 i++
129 buf.WriteString(strconv.Itoa(i) + ": octal format\n")
130 case hex:
131 i++
132 buf.WriteString(strconv.Itoa(i) + ": hex format\n")
133 case exponent:
134 i++
135 buf.WriteString(strconv.Itoa(i) + ": exponent format\n")
136 default:
137 i++
138 buf.WriteString(strconv.Itoa(i) + ": integer format\n")
139 }
140
141 if b.negative {
142 i++
143 buf.WriteString(strconv.Itoa(i) + ": negative format\n")
144 }
145
146 if b.negativeExponent {
147 i++
148 buf.WriteString(strconv.Itoa(i) + ": negative exponent format\n")
149 }
150
151 return buf.String()
152}
diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/op_tokens.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/op_tokens.go
new file mode 100644
index 0000000..8a84c7c
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/op_tokens.go
@@ -0,0 +1,39 @@
1package ini
2
3import (
4 "fmt"
5)
6
7var (
8 equalOp = []rune("=")
9 equalColonOp = []rune(":")
10)
11
12func isOp(b []rune) bool {
13 if len(b) == 0 {
14 return false
15 }
16
17 switch b[0] {
18 case '=':
19 return true
20 case ':':
21 return true
22 default:
23 return false
24 }
25}
26
27func newOpToken(b []rune) (Token, int, error) {
28 tok := Token{}
29
30 switch b[0] {
31 case '=':
32 tok = newToken(TokenOp, equalOp, NoneType)
33 case ':':
34 tok = newToken(TokenOp, equalColonOp, NoneType)
35 default:
36 return tok, 0, NewParseError(fmt.Sprintf("unexpected op type, %v", b[0]))
37 }
38 return tok, 1, nil
39}
diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/parse_error.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/parse_error.go
new file mode 100644
index 0000000..4572870
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/parse_error.go
@@ -0,0 +1,43 @@
1package ini
2
3import "fmt"
4
5const (
6 // ErrCodeParseError is returned when a parsing error
7 // has occurred.
8 ErrCodeParseError = "INIParseError"
9)
10
11// ParseError is an error which is returned during any part of
12// the parsing process.
13type ParseError struct {
14 msg string
15}
16
17// NewParseError will return a new ParseError where message
18// is the description of the error.
19func NewParseError(message string) *ParseError {
20 return &ParseError{
21 msg: message,
22 }
23}
24
25// Code will return the ErrCodeParseError
26func (err *ParseError) Code() string {
27 return ErrCodeParseError
28}
29
30// Message returns the error's message
31func (err *ParseError) Message() string {
32 return err.msg
33}
34
35// OrigError return nothing since there will never be any
36// original error.
37func (err *ParseError) OrigError() error {
38 return nil
39}
40
41func (err *ParseError) Error() string {
42 return fmt.Sprintf("%s: %s", err.Code(), err.Message())
43}
diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/parse_stack.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/parse_stack.go
new file mode 100644
index 0000000..7f01cf7
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/parse_stack.go
@@ -0,0 +1,60 @@
1package ini
2
3import (
4 "bytes"
5 "fmt"
6)
7
8// ParseStack is a stack that contains a container, the stack portion,
9// and the list which is the list of ASTs that have been successfully
10// parsed.
11type ParseStack struct {
12 top int
13 container []AST
14 list []AST
15 index int
16}
17
18func newParseStack(sizeContainer, sizeList int) ParseStack {
19 return ParseStack{
20 container: make([]AST, sizeContainer),
21 list: make([]AST, sizeList),
22 }
23}
24
25// Pop will return and truncate the last container element.
26func (s *ParseStack) Pop() AST {
27 s.top--
28 return s.container[s.top]
29}
30
31// Push will add the new AST to the container
32func (s *ParseStack) Push(ast AST) {
33 s.container[s.top] = ast
34 s.top++
35}
36
37// MarkComplete will append the AST to the list of completed statements
38func (s *ParseStack) MarkComplete(ast AST) {
39 s.list[s.index] = ast
40 s.index++
41}
42
43// List will return the completed statements
44func (s ParseStack) List() []AST {
45 return s.list[:s.index]
46}
47
48// Len will return the length of the container
49func (s *ParseStack) Len() int {
50 return s.top
51}
52
53func (s ParseStack) String() string {
54 buf := bytes.Buffer{}
55 for i, node := range s.list {
56 buf.WriteString(fmt.Sprintf("%d: %v\n", i+1, node))
57 }
58
59 return buf.String()
60}
diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/sep_tokens.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/sep_tokens.go
new file mode 100644
index 0000000..f82095b
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/sep_tokens.go
@@ -0,0 +1,41 @@
1package ini
2
3import (
4 "fmt"
5)
6
7var (
8 emptyRunes = []rune{}
9)
10
11func isSep(b []rune) bool {
12 if len(b) == 0 {
13 return false
14 }
15
16 switch b[0] {
17 case '[', ']':
18 return true
19 default:
20 return false
21 }
22}
23
24var (
25 openBrace = []rune("[")
26 closeBrace = []rune("]")
27)
28
29func newSepToken(b []rune) (Token, int, error) {
30 tok := Token{}
31
32 switch b[0] {
33 case '[':
34 tok = newToken(TokenSep, openBrace, NoneType)
35 case ']':
36 tok = newToken(TokenSep, closeBrace, NoneType)
37 default:
38 return tok, 0, NewParseError(fmt.Sprintf("unexpected sep type, %v", b[0]))
39 }
40 return tok, 1, nil
41}
diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/skipper.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/skipper.go
new file mode 100644
index 0000000..6bb6964
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/skipper.go
@@ -0,0 +1,45 @@
1package ini
2
3// skipper is used to skip certain blocks of an ini file.
4// Currently skipper is used to skip nested blocks of ini
5// files. See example below
6//
7// [ foo ]
8// nested = ; this section will be skipped
9// a=b
10// c=d
11// bar=baz ; this will be included
12type skipper struct {
13 shouldSkip bool
14 TokenSet bool
15 prevTok Token
16}
17
18func newSkipper() skipper {
19 return skipper{
20 prevTok: emptyToken,
21 }
22}
23
24func (s *skipper) ShouldSkip(tok Token) bool {
25 if s.shouldSkip &&
26 s.prevTok.Type() == TokenNL &&
27 tok.Type() != TokenWS {
28
29 s.Continue()
30 return false
31 }
32 s.prevTok = tok
33
34 return s.shouldSkip
35}
36
37func (s *skipper) Skip() {
38 s.shouldSkip = true
39 s.prevTok = emptyToken
40}
41
42func (s *skipper) Continue() {
43 s.shouldSkip = false
44 s.prevTok = emptyToken
45}
diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/statement.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/statement.go
new file mode 100644
index 0000000..18f3fe8
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/statement.go
@@ -0,0 +1,35 @@
1package ini
2
3// Statement is an empty AST mostly used for transitioning states.
4func newStatement() AST {
5 return newAST(ASTKindStatement, AST{})
6}
7
8// SectionStatement represents a section AST
9func newSectionStatement(tok Token) AST {
10 return newASTWithRootToken(ASTKindSectionStatement, tok)
11}
12
13// ExprStatement represents a completed expression AST
14func newExprStatement(ast AST) AST {
15 return newAST(ASTKindExprStatement, ast)
16}
17
18// CommentStatement represents a comment in the ini definition.
19//
20// grammar:
21// comment -> #comment' | ;comment'
22// comment' -> epsilon | value
23func newCommentStatement(tok Token) AST {
24 return newAST(ASTKindCommentStatement, newExpression(tok))
25}
26
27// CompletedSectionStatement represents a completed section
28func newCompletedSectionStatement(ast AST) AST {
29 return newAST(ASTKindCompletedSectionStatement, ast)
30}
31
32// SkipStatement is used to skip whole statements
33func newSkipStatement(ast AST) AST {
34 return newAST(ASTKindSkipStatement, ast)
35}
diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/value_util.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/value_util.go
new file mode 100644
index 0000000..305999d
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/value_util.go
@@ -0,0 +1,284 @@
1package ini
2
3import (
4 "fmt"
5)
6
7// getStringValue will return a quoted string and the amount
8// of bytes read
9//
10// an error will be returned if the string is not properly formatted
11func getStringValue(b []rune) (int, error) {
12 if b[0] != '"' {
13 return 0, NewParseError("strings must start with '\"'")
14 }
15
16 endQuote := false
17 i := 1
18
19 for ; i < len(b) && !endQuote; i++ {
20 if escaped := isEscaped(b[:i], b[i]); b[i] == '"' && !escaped {
21 endQuote = true
22 break
23 } else if escaped {
24 /*c, err := getEscapedByte(b[i])
25 if err != nil {
26 return 0, err
27 }
28
29 b[i-1] = c
30 b = append(b[:i], b[i+1:]...)
31 i--*/
32
33 continue
34 }
35 }
36
37 if !endQuote {
38 return 0, NewParseError("missing '\"' in string value")
39 }
40
41 return i + 1, nil
42}
43
44// getBoolValue will return a boolean and the amount
45// of bytes read
46//
47// an error will be returned if the boolean is not of a correct
48// value
49func getBoolValue(b []rune) (int, error) {
50 if len(b) < 4 {
51 return 0, NewParseError("invalid boolean value")
52 }
53
54 n := 0
55 for _, lv := range literalValues {
56 if len(lv) > len(b) {
57 continue
58 }
59
60 if isLitValue(lv, b) {
61 n = len(lv)
62 }
63 }
64
65 if n == 0 {
66 return 0, NewParseError("invalid boolean value")
67 }
68
69 return n, nil
70}
71
72// getNumericalValue will return a numerical string, the amount
73// of bytes read, and the base of the number
74//
75// an error will be returned if the number is not of a correct
76// value
77func getNumericalValue(b []rune) (int, int, error) {
78 if !isDigit(b[0]) {
79 return 0, 0, NewParseError("invalid digit value")
80 }
81
82 i := 0
83 helper := numberHelper{}
84
85loop:
86 for negativeIndex := 0; i < len(b); i++ {
87 negativeIndex++
88
89 if !isDigit(b[i]) {
90 switch b[i] {
91 case '-':
92 if helper.IsNegative() || negativeIndex != 1 {
93 return 0, 0, NewParseError("parse error '-'")
94 }
95
96 n := getNegativeNumber(b[i:])
97 i += (n - 1)
98 helper.Determine(b[i])
99 continue
100 case '.':
101 if err := helper.Determine(b[i]); err != nil {
102 return 0, 0, err
103 }
104 case 'e', 'E':
105 if err := helper.Determine(b[i]); err != nil {
106 return 0, 0, err
107 }
108
109 negativeIndex = 0
110 case 'b':
111 if helper.numberFormat == hex {
112 break
113 }
114 fallthrough
115 case 'o', 'x':
116 if i == 0 && b[i] != '0' {
117 return 0, 0, NewParseError("incorrect base format, expected leading '0'")
118 }
119
120 if i != 1 {
121 return 0, 0, NewParseError(fmt.Sprintf("incorrect base format found %s at %d index", string(b[i]), i))
122 }
123
124 if err := helper.Determine(b[i]); err != nil {
125 return 0, 0, err
126 }
127 default:
128 if isWhitespace(b[i]) {
129 break loop
130 }
131
132 if isNewline(b[i:]) {
133 break loop
134 }
135
136 if !(helper.numberFormat == hex && isHexByte(b[i])) {
137 if i+2 < len(b) && !isNewline(b[i:i+2]) {
138 return 0, 0, NewParseError("invalid numerical character")
139 } else if !isNewline([]rune{b[i]}) {
140 return 0, 0, NewParseError("invalid numerical character")
141 }
142
143 break loop
144 }
145 }
146 }
147 }
148
149 return helper.Base(), i, nil
150}
151
152// isDigit will return whether or not something is an integer
153func isDigit(b rune) bool {
154 return b >= '0' && b <= '9'
155}
156
157func hasExponent(v []rune) bool {
158 return contains(v, 'e') || contains(v, 'E')
159}
160
161func isBinaryByte(b rune) bool {
162 switch b {
163 case '0', '1':
164 return true
165 default:
166 return false
167 }
168}
169
170func isOctalByte(b rune) bool {
171 switch b {
172 case '0', '1', '2', '3', '4', '5', '6', '7':
173 return true
174 default:
175 return false
176 }
177}
178
179func isHexByte(b rune) bool {
180 if isDigit(b) {
181 return true
182 }
183 return (b >= 'A' && b <= 'F') ||
184 (b >= 'a' && b <= 'f')
185}
186
187func getValue(b []rune) (int, error) {
188 i := 0
189
190 for i < len(b) {
191 if isNewline(b[i:]) {
192 break
193 }
194
195 if isOp(b[i:]) {
196 break
197 }
198
199 valid, n, err := isValid(b[i:])
200 if err != nil {
201 return 0, err
202 }
203
204 if !valid {
205 break
206 }
207
208 i += n
209 }
210
211 return i, nil
212}
213
214// getNegativeNumber will return a negative number from a
215// byte slice. This will iterate through all characters until
216// a non-digit has been found.
217func getNegativeNumber(b []rune) int {
218 if b[0] != '-' {
219 return 0
220 }
221
222 i := 1
223 for ; i < len(b); i++ {
224 if !isDigit(b[i]) {
225 return i
226 }
227 }
228
229 return i
230}
231
232// isEscaped will return whether or not the character is an escaped
233// character.
234func isEscaped(value []rune, b rune) bool {
235 if len(value) == 0 {
236 return false
237 }
238
239 switch b {
240 case '\'': // single quote
241 case '"': // quote
242 case 'n': // newline
243 case 't': // tab
244 case '\\': // backslash
245 default:
246 return false
247 }
248
249 return value[len(value)-1] == '\\'
250}
251
252func getEscapedByte(b rune) (rune, error) {
253 switch b {
254 case '\'': // single quote
255 return '\'', nil
256 case '"': // quote
257 return '"', nil
258 case 'n': // newline
259 return '\n', nil
260 case 't': // table
261 return '\t', nil
262 case '\\': // backslash
263 return '\\', nil
264 default:
265 return b, NewParseError(fmt.Sprintf("invalid escaped character %c", b))
266 }
267}
268
269func removeEscapedCharacters(b []rune) []rune {
270 for i := 0; i < len(b); i++ {
271 if isEscaped(b[:i], b[i]) {
272 c, err := getEscapedByte(b[i])
273 if err != nil {
274 return b
275 }
276
277 b[i-1] = c
278 b = append(b[:i], b[i+1:]...)
279 i--
280 }
281 }
282
283 return b
284}
diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/visitor.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/visitor.go
new file mode 100644
index 0000000..94841c3
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/visitor.go
@@ -0,0 +1,166 @@
1package ini
2
3import (
4 "fmt"
5 "sort"
6)
7
8// Visitor is an interface used by walkers that will
9// traverse an array of ASTs.
10type Visitor interface {
11 VisitExpr(AST) error
12 VisitStatement(AST) error
13}
14
15// DefaultVisitor is used to visit statements and expressions
16// and ensure that they are both of the correct format.
17// In addition, upon visiting this will build sections and populate
18// the Sections field which can be used to retrieve profile
19// configuration.
20type DefaultVisitor struct {
21 scope string
22 Sections Sections
23}
24
25// NewDefaultVisitor return a DefaultVisitor
26func NewDefaultVisitor() *DefaultVisitor {
27 return &DefaultVisitor{
28 Sections: Sections{
29 container: map[string]Section{},
30 },
31 }
32}
33
34// VisitExpr visits expressions...
35func (v *DefaultVisitor) VisitExpr(expr AST) error {
36 t := v.Sections.container[v.scope]
37 if t.values == nil {
38 t.values = values{}
39 }
40
41 switch expr.Kind {
42 case ASTKindExprStatement:
43 opExpr := expr.GetRoot()
44 switch opExpr.Kind {
45 case ASTKindEqualExpr:
46 children := opExpr.GetChildren()
47 if len(children) <= 1 {
48 return NewParseError("unexpected token type")
49 }
50
51 rhs := children[1]
52
53 if rhs.Root.Type() != TokenLit {
54 return NewParseError("unexpected token type")
55 }
56
57 key := EqualExprKey(opExpr)
58 v, err := newValue(rhs.Root.ValueType, rhs.Root.base, rhs.Root.Raw())
59 if err != nil {
60 return err
61 }
62
63 t.values[key] = v
64 default:
65 return NewParseError(fmt.Sprintf("unsupported expression %v", expr))
66 }
67 default:
68 return NewParseError(fmt.Sprintf("unsupported expression %v", expr))
69 }
70
71 v.Sections.container[v.scope] = t
72 return nil
73}
74
75// VisitStatement visits statements...
76func (v *DefaultVisitor) VisitStatement(stmt AST) error {
77 switch stmt.Kind {
78 case ASTKindCompletedSectionStatement:
79 child := stmt.GetRoot()
80 if child.Kind != ASTKindSectionStatement {
81 return NewParseError(fmt.Sprintf("unsupported child statement: %T", child))
82 }
83
84 name := string(child.Root.Raw())
85 v.Sections.container[name] = Section{}
86 v.scope = name
87 default:
88 return NewParseError(fmt.Sprintf("unsupported statement: %s", stmt.Kind))
89 }
90
91 return nil
92}
93
94// Sections is a map of Section structures that represent
95// a configuration.
96type Sections struct {
97 container map[string]Section
98}
99
100// GetSection will return section p. If section p does not exist,
101// false will be returned in the second parameter.
102func (t Sections) GetSection(p string) (Section, bool) {
103 v, ok := t.container[p]
104 return v, ok
105}
106
107// values represents a map of union values.
108type values map[string]Value
109
110// List will return a list of all sections that were successfully
111// parsed.
112func (t Sections) List() []string {
113 keys := make([]string, len(t.container))
114 i := 0
115 for k := range t.container {
116 keys[i] = k
117 i++
118 }
119
120 sort.Strings(keys)
121 return keys
122}
123
124// Section contains a name and values. This represent
125// a sectioned entry in a configuration file.
126type Section struct {
127 Name string
128 values values
129}
130
131// Has will return whether or not an entry exists in a given section
132func (t Section) Has(k string) bool {
133 _, ok := t.values[k]
134 return ok
135}
136
137// ValueType will returned what type the union is set to. If
138// k was not found, the NoneType will be returned.
139func (t Section) ValueType(k string) (ValueType, bool) {
140 v, ok := t.values[k]
141 return v.Type, ok
142}
143
144// Bool returns a bool value at k
145func (t Section) Bool(k string) bool {
146 return t.values[k].BoolValue()
147}
148
149// Int returns an integer value at k
150func (t Section) Int(k string) int64 {
151 return t.values[k].IntValue()
152}
153
154// Float64 returns a float value at k
155func (t Section) Float64(k string) float64 {
156 return t.values[k].FloatValue()
157}
158
159// String returns the string value at k
160func (t Section) String(k string) string {
161 _, ok := t.values[k]
162 if !ok {
163 return ""
164 }
165 return t.values[k].StringValue()
166}
diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/walker.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/walker.go
new file mode 100644
index 0000000..99915f7
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/walker.go
@@ -0,0 +1,25 @@
1package ini
2
3// Walk will traverse the AST using the v, the Visitor.
4func Walk(tree []AST, v Visitor) error {
5 for _, node := range tree {
6 switch node.Kind {
7 case ASTKindExpr,
8 ASTKindExprStatement:
9
10 if err := v.VisitExpr(node); err != nil {
11 return err
12 }
13 case ASTKindStatement,
14 ASTKindCompletedSectionStatement,
15 ASTKindNestedSectionStatement,
16 ASTKindCompletedNestedSectionStatement:
17
18 if err := v.VisitStatement(node); err != nil {
19 return err
20 }
21 }
22 }
23
24 return nil
25}
diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/ws_token.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/ws_token.go
new file mode 100644
index 0000000..7ffb4ae
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/ws_token.go
@@ -0,0 +1,24 @@
1package ini
2
3import (
4 "unicode"
5)
6
7// isWhitespace will return whether or not the character is
8// a whitespace character.
9//
10// Whitespace is defined as a space or tab.
11func isWhitespace(c rune) bool {
12 return unicode.IsSpace(c) && c != '\n' && c != '\r'
13}
14
15func newWSToken(b []rune) (Token, int, error) {
16 i := 0
17 for ; i < len(b); i++ {
18 if !isWhitespace(b[i]) {
19 break
20 }
21 }
22
23 return newToken(TokenWS, b[:i], NoneType), i, nil
24}