aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/zclconf/go-cty/cty/function
diff options
context:
space:
mode:
authorNathan Dench <ndenc2@gmail.com>2019-05-24 15:16:44 +1000
committerNathan Dench <ndenc2@gmail.com>2019-05-24 15:16:44 +1000
commit107c1cdb09c575aa2f61d97f48d8587eb6bada4c (patch)
treeca7d008643efc555c388baeaf1d986e0b6b3e28c /vendor/github.com/zclconf/go-cty/cty/function
parent844b5a68d8af4791755b8f0ad293cc99f5959183 (diff)
downloadterraform-provider-statuscake-107c1cdb09c575aa2f61d97f48d8587eb6bada4c.tar.gz
terraform-provider-statuscake-107c1cdb09c575aa2f61d97f48d8587eb6bada4c.tar.zst
terraform-provider-statuscake-107c1cdb09c575aa2f61d97f48d8587eb6bada4c.zip
Upgrade to 0.12
Diffstat (limited to 'vendor/github.com/zclconf/go-cty/cty/function')
-rw-r--r--vendor/github.com/zclconf/go-cty/cty/function/function.go4
-rw-r--r--vendor/github.com/zclconf/go-cty/cty/function/stdlib/datetime.go385
-rw-r--r--vendor/github.com/zclconf/go-cty/cty/function/stdlib/format.go5
-rw-r--r--vendor/github.com/zclconf/go-cty/cty/function/stdlib/format_fsm.go74
-rw-r--r--vendor/github.com/zclconf/go-cty/cty/function/stdlib/format_fsm.rl18
-rw-r--r--vendor/github.com/zclconf/go-cty/cty/function/stdlib/regexp.go233
-rw-r--r--vendor/github.com/zclconf/go-cty/cty/function/stdlib/sequence.go88
7 files changed, 775 insertions, 32 deletions
diff --git a/vendor/github.com/zclconf/go-cty/cty/function/function.go b/vendor/github.com/zclconf/go-cty/cty/function/function.go
index 162f7bf..9e8bf33 100644
--- a/vendor/github.com/zclconf/go-cty/cty/function/function.go
+++ b/vendor/github.com/zclconf/go-cty/cty/function/function.go
@@ -143,7 +143,7 @@ func (f Function) ReturnTypeForValues(args []cty.Value) (ty cty.Type, err error)
143 val := posArgs[i] 143 val := posArgs[i]
144 144
145 if val.IsNull() && !spec.AllowNull { 145 if val.IsNull() && !spec.AllowNull {
146 return cty.Type{}, NewArgErrorf(i, "must not be null") 146 return cty.Type{}, NewArgErrorf(i, "argument must not be null")
147 } 147 }
148 148
149 // AllowUnknown is ignored for type-checking, since we expect to be 149 // AllowUnknown is ignored for type-checking, since we expect to be
@@ -169,7 +169,7 @@ func (f Function) ReturnTypeForValues(args []cty.Value) (ty cty.Type, err error)
169 realI := i + len(posArgs) 169 realI := i + len(posArgs)
170 170
171 if val.IsNull() && !spec.AllowNull { 171 if val.IsNull() && !spec.AllowNull {
172 return cty.Type{}, NewArgErrorf(realI, "must not be null") 172 return cty.Type{}, NewArgErrorf(realI, "argument must not be null")
173 } 173 }
174 174
175 if val.Type() == cty.DynamicPseudoType { 175 if val.Type() == cty.DynamicPseudoType {
diff --git a/vendor/github.com/zclconf/go-cty/cty/function/stdlib/datetime.go b/vendor/github.com/zclconf/go-cty/cty/function/stdlib/datetime.go
new file mode 100644
index 0000000..aa15b7b
--- /dev/null
+++ b/vendor/github.com/zclconf/go-cty/cty/function/stdlib/datetime.go
@@ -0,0 +1,385 @@
1package stdlib
2
3import (
4 "bufio"
5 "bytes"
6 "fmt"
7 "strings"
8 "time"
9
10 "github.com/zclconf/go-cty/cty"
11 "github.com/zclconf/go-cty/cty/function"
12)
13
14var FormatDateFunc = function.New(&function.Spec{
15 Params: []function.Parameter{
16 {
17 Name: "format",
18 Type: cty.String,
19 },
20 {
21 Name: "time",
22 Type: cty.String,
23 },
24 },
25 Type: function.StaticReturnType(cty.String),
26 Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
27 formatStr := args[0].AsString()
28 timeStr := args[1].AsString()
29 t, err := parseTimestamp(timeStr)
30 if err != nil {
31 return cty.DynamicVal, function.NewArgError(1, err)
32 }
33
34 var buf bytes.Buffer
35 sc := bufio.NewScanner(strings.NewReader(formatStr))
36 sc.Split(splitDateFormat)
37 const esc = '\''
38 for sc.Scan() {
39 tok := sc.Bytes()
40
41 // The leading byte signals the token type
42 switch {
43 case tok[0] == esc:
44 if tok[len(tok)-1] != esc || len(tok) == 1 {
45 return cty.DynamicVal, function.NewArgErrorf(0, "unterminated literal '")
46 }
47 if len(tok) == 2 {
48 // Must be a single escaped quote, ''
49 buf.WriteByte(esc)
50 } else {
51 // The content (until a closing esc) is printed out verbatim
52 // except that we must un-double any double-esc escapes in
53 // the middle of the string.
54 raw := tok[1 : len(tok)-1]
55 for i := 0; i < len(raw); i++ {
56 buf.WriteByte(raw[i])
57 if raw[i] == esc {
58 i++ // skip the escaped quote
59 }
60 }
61 }
62
63 case startsDateFormatVerb(tok[0]):
64 switch tok[0] {
65 case 'Y':
66 y := t.Year()
67 switch len(tok) {
68 case 2:
69 fmt.Fprintf(&buf, "%02d", y%100)
70 case 4:
71 fmt.Fprintf(&buf, "%04d", y)
72 default:
73 return cty.DynamicVal, function.NewArgErrorf(0, "invalid date format verb %q: year must either be \"YY\" or \"YYYY\"", tok)
74 }
75 case 'M':
76 m := t.Month()
77 switch len(tok) {
78 case 1:
79 fmt.Fprintf(&buf, "%d", m)
80 case 2:
81 fmt.Fprintf(&buf, "%02d", m)
82 case 3:
83 buf.WriteString(m.String()[:3])
84 case 4:
85 buf.WriteString(m.String())
86 default:
87 return cty.DynamicVal, function.NewArgErrorf(0, "invalid date format verb %q: month must be \"M\", \"MM\", \"MMM\", or \"MMMM\"", tok)
88 }
89 case 'D':
90 d := t.Day()
91 switch len(tok) {
92 case 1:
93 fmt.Fprintf(&buf, "%d", d)
94 case 2:
95 fmt.Fprintf(&buf, "%02d", d)
96 default:
97 return cty.DynamicVal, function.NewArgErrorf(0, "invalid date format verb %q: day of month must either be \"D\" or \"DD\"", tok)
98 }
99 case 'E':
100 d := t.Weekday()
101 switch len(tok) {
102 case 3:
103 buf.WriteString(d.String()[:3])
104 case 4:
105 buf.WriteString(d.String())
106 default:
107 return cty.DynamicVal, function.NewArgErrorf(0, "invalid date format verb %q: day of week must either be \"EEE\" or \"EEEE\"", tok)
108 }
109 case 'h':
110 h := t.Hour()
111 switch len(tok) {
112 case 1:
113 fmt.Fprintf(&buf, "%d", h)
114 case 2:
115 fmt.Fprintf(&buf, "%02d", h)
116 default:
117 return cty.DynamicVal, function.NewArgErrorf(0, "invalid date format verb %q: 24-hour must either be \"h\" or \"hh\"", tok)
118 }
119 case 'H':
120 h := t.Hour() % 12
121 if h == 0 {
122 h = 12
123 }
124 switch len(tok) {
125 case 1:
126 fmt.Fprintf(&buf, "%d", h)
127 case 2:
128 fmt.Fprintf(&buf, "%02d", h)
129 default:
130 return cty.DynamicVal, function.NewArgErrorf(0, "invalid date format verb %q: 12-hour must either be \"H\" or \"HH\"", tok)
131 }
132 case 'A', 'a':
133 if len(tok) != 2 {
134 return cty.DynamicVal, function.NewArgErrorf(0, "invalid date format verb %q: must be \"%s%s\"", tok, tok[0:1], tok[0:1])
135 }
136 upper := tok[0] == 'A'
137 switch t.Hour() / 12 {
138 case 0:
139 if upper {
140 buf.WriteString("AM")
141 } else {
142 buf.WriteString("am")
143 }
144 case 1:
145 if upper {
146 buf.WriteString("PM")
147 } else {
148 buf.WriteString("pm")
149 }
150 }
151 case 'm':
152 m := t.Minute()
153 switch len(tok) {
154 case 1:
155 fmt.Fprintf(&buf, "%d", m)
156 case 2:
157 fmt.Fprintf(&buf, "%02d", m)
158 default:
159 return cty.DynamicVal, function.NewArgErrorf(0, "invalid date format verb %q: minute must either be \"m\" or \"mm\"", tok)
160 }
161 case 's':
162 s := t.Second()
163 switch len(tok) {
164 case 1:
165 fmt.Fprintf(&buf, "%d", s)
166 case 2:
167 fmt.Fprintf(&buf, "%02d", s)
168 default:
169 return cty.DynamicVal, function.NewArgErrorf(0, "invalid date format verb %q: second must either be \"s\" or \"ss\"", tok)
170 }
171 case 'Z':
172 // We'll just lean on Go's own formatter for this one, since
173 // the necessary information is unexported.
174 switch len(tok) {
175 case 1:
176 buf.WriteString(t.Format("Z07:00"))
177 case 3:
178 str := t.Format("-0700")
179 switch str {
180 case "+0000":
181 buf.WriteString("UTC")
182 default:
183 buf.WriteString(str)
184 }
185 case 4:
186 buf.WriteString(t.Format("-0700"))
187 case 5:
188 buf.WriteString(t.Format("-07:00"))
189 default:
190 return cty.DynamicVal, function.NewArgErrorf(0, "invalid date format verb %q: timezone must be Z, ZZZZ, or ZZZZZ", tok)
191 }
192 default:
193 return cty.DynamicVal, function.NewArgErrorf(0, "invalid date format verb %q", tok)
194 }
195
196 default:
197 // Any other starting character indicates a literal sequence
198 buf.Write(tok)
199 }
200 }
201
202 return cty.StringVal(buf.String()), nil
203 },
204})
205
206// FormatDate reformats a timestamp given in RFC3339 syntax into another time
207// syntax defined by a given format string.
208//
209// The format string uses letter mnemonics to represent portions of the
210// timestamp, with repetition signifying length variants of each portion.
211// Single quote characters ' can be used to quote sequences of literal letters
212// that should not be interpreted as formatting mnemonics.
213//
214// The full set of supported mnemonic sequences is listed below:
215//
216// YY Year modulo 100 zero-padded to two digits, like "06".
217// YYYY Four (or more) digit year, like "2006".
218// M Month number, like "1" for January.
219// MM Month number zero-padded to two digits, like "01".
220// MMM English month name abbreviated to three letters, like "Jan".
221// MMMM English month name unabbreviated, like "January".
222// D Day of month number, like "2".
223// DD Day of month number zero-padded to two digits, like "02".
224// EEE English day of week name abbreviated to three letters, like "Mon".
225// EEEE English day of week name unabbreviated, like "Monday".
226// h 24-hour number, like "2".
227// hh 24-hour number zero-padded to two digits, like "02".
228// H 12-hour number, like "2".
229// HH 12-hour number zero-padded to two digits, like "02".
230// AA Hour AM/PM marker in uppercase, like "AM".
231// aa Hour AM/PM marker in lowercase, like "am".
232// m Minute within hour, like "5".
233// mm Minute within hour zero-padded to two digits, like "05".
234// s Second within minute, like "9".
235// ss Second within minute zero-padded to two digits, like "09".
236// ZZZZ Timezone offset with just sign and digit, like "-0800".
237// ZZZZZ Timezone offset with colon separating hours and minutes, like "-08:00".
238// Z Like ZZZZZ but with a special case "Z" for UTC.
239// ZZZ Like ZZZZ but with a special case "UTC" for UTC.
240//
241// The format syntax is optimized mainly for generating machine-oriented
242// timestamps rather than human-oriented timestamps; the English language
243// portions of the output reflect the use of English names in a number of
244// machine-readable date formatting standards. For presentation to humans,
245// a locale-aware time formatter (not included in this package) is a better
246// choice.
247//
248// The format syntax is not compatible with that of any other language, but
249// is optimized so that patterns for common standard date formats can be
250// recognized quickly even by a reader unfamiliar with the format syntax.
251func FormatDate(format cty.Value, timestamp cty.Value) (cty.Value, error) {
252 return FormatDateFunc.Call([]cty.Value{format, timestamp})
253}
254
255func parseTimestamp(ts string) (time.Time, error) {
256 t, err := time.Parse(time.RFC3339, ts)
257 if err != nil {
258 switch err := err.(type) {
259 case *time.ParseError:
260 // If err is s time.ParseError then its string representation is not
261 // appropriate since it relies on details of Go's strange date format
262 // representation, which a caller of our functions is not expected
263 // to be familiar with.
264 //
265 // Therefore we do some light transformation to get a more suitable
266 // error that should make more sense to our callers. These are
267 // still not awesome error messages, but at least they refer to
268 // the timestamp portions by name rather than by Go's example
269 // values.
270 if err.LayoutElem == "" && err.ValueElem == "" && err.Message != "" {
271 // For some reason err.Message is populated with a ": " prefix
272 // by the time package.
273 return time.Time{}, fmt.Errorf("not a valid RFC3339 timestamp%s", err.Message)
274 }
275 var what string
276 switch err.LayoutElem {
277 case "2006":
278 what = "year"
279 case "01":
280 what = "month"
281 case "02":
282 what = "day of month"
283 case "15":
284 what = "hour"
285 case "04":
286 what = "minute"
287 case "05":
288 what = "second"
289 case "Z07:00":
290 what = "UTC offset"
291 case "T":
292 return time.Time{}, fmt.Errorf("not a valid RFC3339 timestamp: missing required time introducer 'T'")
293 case ":", "-":
294 if err.ValueElem == "" {
295 return time.Time{}, fmt.Errorf("not a valid RFC3339 timestamp: end of string where %q is expected", err.LayoutElem)
296 } else {
297 return time.Time{}, fmt.Errorf("not a valid RFC3339 timestamp: found %q where %q is expected", err.ValueElem, err.LayoutElem)
298 }
299 default:
300 // Should never get here, because time.RFC3339 includes only the
301 // above portions, but since that might change in future we'll
302 // be robust here.
303 what = "timestamp segment"
304 }
305 if err.ValueElem == "" {
306 return time.Time{}, fmt.Errorf("not a valid RFC3339 timestamp: end of string before %s", what)
307 } else {
308 return time.Time{}, fmt.Errorf("not a valid RFC3339 timestamp: cannot use %q as %s", err.ValueElem, what)
309 }
310 }
311 return time.Time{}, err
312 }
313 return t, nil
314}
315
316// splitDataFormat is a bufio.SplitFunc used to tokenize a date format.
317func splitDateFormat(data []byte, atEOF bool) (advance int, token []byte, err error) {
318 if len(data) == 0 {
319 return 0, nil, nil
320 }
321
322 const esc = '\''
323
324 switch {
325
326 case data[0] == esc:
327 // If we have another quote immediately after then this is a single
328 // escaped escape.
329 if len(data) > 1 && data[1] == esc {
330 return 2, data[:2], nil
331 }
332
333 // Beginning of quoted sequence, so we will seek forward until we find
334 // the closing quote, ignoring escaped quotes along the way.
335 for i := 1; i < len(data); i++ {
336 if data[i] == esc {
337 if (i + 1) == len(data) {
338 // We need at least one more byte to decide if this is an
339 // escape or a terminator.
340 return 0, nil, nil
341 }
342 if data[i+1] == esc {
343 i++ // doubled-up quotes are an escape sequence
344 continue
345 }
346 // We've found the closing quote
347 return i + 1, data[:i+1], nil
348 }
349 }
350 // If we fall out here then we need more bytes to find the end,
351 // unless we're already at the end with an unclosed quote.
352 if atEOF {
353 return len(data), data, nil
354 }
355 return 0, nil, nil
356
357 case startsDateFormatVerb(data[0]):
358 rep := data[0]
359 for i := 1; i < len(data); i++ {
360 if data[i] != rep {
361 return i, data[:i], nil
362 }
363 }
364 if atEOF {
365 return len(data), data, nil
366 }
367 // We need more data to decide if we've found the end
368 return 0, nil, nil
369
370 default:
371 for i := 1; i < len(data); i++ {
372 if data[i] == esc || startsDateFormatVerb(data[i]) {
373 return i, data[:i], nil
374 }
375 }
376 // We might not actually be at the end of a literal sequence,
377 // but that doesn't matter since we'll concat them back together
378 // anyway.
379 return len(data), data, nil
380 }
381}
382
383func startsDateFormatVerb(b byte) bool {
384 return (b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z')
385}
diff --git a/vendor/github.com/zclconf/go-cty/cty/function/stdlib/format.go b/vendor/github.com/zclconf/go-cty/cty/function/stdlib/format.go
index fb24f20..664790b 100644
--- a/vendor/github.com/zclconf/go-cty/cty/function/stdlib/format.go
+++ b/vendor/github.com/zclconf/go-cty/cty/function/stdlib/format.go
@@ -84,6 +84,11 @@ var FormatListFunc = function.New(&function.Spec{
84 argTy := arg.Type() 84 argTy := arg.Type()
85 switch { 85 switch {
86 case (argTy.IsListType() || argTy.IsSetType() || argTy.IsTupleType()) && !arg.IsNull(): 86 case (argTy.IsListType() || argTy.IsSetType() || argTy.IsTupleType()) && !arg.IsNull():
87 if !argTy.IsTupleType() && !arg.IsKnown() {
88 // We can't iterate this one at all yet then, so we can't
89 // yet produce a result.
90 return cty.UnknownVal(retType), nil
91 }
87 thisLen := arg.LengthInt() 92 thisLen := arg.LengthInt()
88 if iterLen == -1 { 93 if iterLen == -1 {
89 iterLen = thisLen 94 iterLen = thisLen
diff --git a/vendor/github.com/zclconf/go-cty/cty/function/stdlib/format_fsm.go b/vendor/github.com/zclconf/go-cty/cty/function/stdlib/format_fsm.go
index 86876ba..32b1ac9 100644
--- a/vendor/github.com/zclconf/go-cty/cty/function/stdlib/format_fsm.go
+++ b/vendor/github.com/zclconf/go-cty/cty/function/stdlib/format_fsm.go
@@ -11,9 +11,10 @@ import (
11 "unicode/utf8" 11 "unicode/utf8"
12 12
13 "github.com/zclconf/go-cty/cty" 13 "github.com/zclconf/go-cty/cty"
14 "github.com/zclconf/go-cty/cty/function"
14) 15)
15 16
16// line 20 "format_fsm.go" 17// line 21 "format_fsm.go"
17var _formatfsm_actions []byte = []byte{ 18var _formatfsm_actions []byte = []byte{
18 0, 1, 0, 1, 1, 1, 2, 1, 4, 19 0, 1, 0, 1, 1, 1, 2, 1, 4,
19 1, 5, 1, 6, 1, 7, 1, 8, 20 1, 5, 1, 6, 1, 7, 1, 8,
@@ -86,15 +87,16 @@ const formatfsm_error int = 0
86 87
87const formatfsm_en_main int = 8 88const formatfsm_en_main int = 8
88 89
89// line 19 "format_fsm.rl" 90// line 20 "format_fsm.rl"
90 91
91func formatFSM(format string, a []cty.Value) (string, error) { 92func formatFSM(format string, a []cty.Value) (string, error) {
92 var buf bytes.Buffer 93 var buf bytes.Buffer
93 data := format 94 data := format
94 nextArg := 1 // arg numbers are 1-based 95 nextArg := 1 // arg numbers are 1-based
95 var verb formatVerb 96 var verb formatVerb
97 highestArgIdx := 0 // zero means "none", since arg numbers are 1-based
96 98
97 // line 153 "format_fsm.rl" 99 // line 159 "format_fsm.rl"
98 100
99 // Ragel state 101 // Ragel state
100 p := 0 // "Pointer" into data 102 p := 0 // "Pointer" into data
@@ -109,12 +111,12 @@ func formatFSM(format string, a []cty.Value) (string, error) {
109 _ = te 111 _ = te
110 _ = eof 112 _ = eof
111 113
112 // line 121 "format_fsm.go" 114 // line 123 "format_fsm.go"
113 { 115 {
114 cs = formatfsm_start 116 cs = formatfsm_start
115 } 117 }
116 118
117 // line 126 "format_fsm.go" 119 // line 128 "format_fsm.go"
118 { 120 {
119 var _klen int 121 var _klen int
120 var _trans int 122 var _trans int
@@ -195,7 +197,7 @@ func formatFSM(format string, a []cty.Value) (string, error) {
195 _acts++ 197 _acts++
196 switch _formatfsm_actions[_acts-1] { 198 switch _formatfsm_actions[_acts-1] {
197 case 0: 199 case 0:
198 // line 29 "format_fsm.rl" 200 // line 31 "format_fsm.rl"
199 201
200 verb = formatVerb{ 202 verb = formatVerb{
201 ArgNum: nextArg, 203 ArgNum: nextArg,
@@ -205,12 +207,12 @@ func formatFSM(format string, a []cty.Value) (string, error) {
205 ts = p 207 ts = p
206 208
207 case 1: 209 case 1:
208 // line 38 "format_fsm.rl" 210 // line 40 "format_fsm.rl"
209 211
210 buf.WriteByte(data[p]) 212 buf.WriteByte(data[p])
211 213
212 case 4: 214 case 4:
213 // line 49 "format_fsm.rl" 215 // line 51 "format_fsm.rl"
214 216
215 // We'll try to slurp a whole UTF-8 sequence here, to give the user 217 // We'll try to slurp a whole UTF-8 sequence here, to give the user
216 // better feedback. 218 // better feedback.
@@ -218,85 +220,89 @@ func formatFSM(format string, a []cty.Value) (string, error) {
218 return buf.String(), fmt.Errorf("unrecognized format character %q at offset %d", r, p) 220 return buf.String(), fmt.Errorf("unrecognized format character %q at offset %d", r, p)
219 221
220 case 5: 222 case 5:
221 // line 56 "format_fsm.rl" 223 // line 58 "format_fsm.rl"
222 224
223 verb.Sharp = true 225 verb.Sharp = true
224 226
225 case 6: 227 case 6:
226 // line 59 "format_fsm.rl" 228 // line 61 "format_fsm.rl"
227 229
228 verb.Zero = true 230 verb.Zero = true
229 231
230 case 7: 232 case 7:
231 // line 62 "format_fsm.rl" 233 // line 64 "format_fsm.rl"
232 234
233 verb.Minus = true 235 verb.Minus = true
234 236
235 case 8: 237 case 8:
236 // line 65 "format_fsm.rl" 238 // line 67 "format_fsm.rl"
237 239
238 verb.Plus = true 240 verb.Plus = true
239 241
240 case 9: 242 case 9:
241 // line 68 "format_fsm.rl" 243 // line 70 "format_fsm.rl"
242 244
243 verb.Space = true 245 verb.Space = true
244 246
245 case 10: 247 case 10:
246 // line 72 "format_fsm.rl" 248 // line 74 "format_fsm.rl"
247 249
248 verb.ArgNum = 0 250 verb.ArgNum = 0
249 251
250 case 11: 252 case 11:
251 // line 75 "format_fsm.rl" 253 // line 77 "format_fsm.rl"
252 254
253 verb.ArgNum = (10 * verb.ArgNum) + (int(data[p]) - '0') 255 verb.ArgNum = (10 * verb.ArgNum) + (int(data[p]) - '0')
254 256
255 case 12: 257 case 12:
256 // line 79 "format_fsm.rl" 258 // line 81 "format_fsm.rl"
257 259
258 verb.HasWidth = true 260 verb.HasWidth = true
259 261
260 case 13: 262 case 13:
261 // line 82 "format_fsm.rl" 263 // line 84 "format_fsm.rl"
262 264
263 verb.Width = 0 265 verb.Width = 0
264 266
265 case 14: 267 case 14:
266 // line 85 "format_fsm.rl" 268 // line 87 "format_fsm.rl"
267 269
268 verb.Width = (10 * verb.Width) + (int(data[p]) - '0') 270 verb.Width = (10 * verb.Width) + (int(data[p]) - '0')
269 271
270 case 15: 272 case 15:
271 // line 89 "format_fsm.rl" 273 // line 91 "format_fsm.rl"
272 274
273 verb.HasPrec = true 275 verb.HasPrec = true
274 276
275 case 16: 277 case 16:
276 // line 92 "format_fsm.rl" 278 // line 94 "format_fsm.rl"
277 279
278 verb.Prec = 0 280 verb.Prec = 0
279 281
280 case 17: 282 case 17:
281 // line 95 "format_fsm.rl" 283 // line 97 "format_fsm.rl"
282 284
283 verb.Prec = (10 * verb.Prec) + (int(data[p]) - '0') 285 verb.Prec = (10 * verb.Prec) + (int(data[p]) - '0')
284 286
285 case 18: 287 case 18:
286 // line 99 "format_fsm.rl" 288 // line 101 "format_fsm.rl"
287 289
288 verb.Mode = rune(data[p]) 290 verb.Mode = rune(data[p])
289 te = p + 1 291 te = p + 1
290 verb.Raw = data[ts:te] 292 verb.Raw = data[ts:te]
291 verb.Offset = ts 293 verb.Offset = ts
292 294
295 if verb.ArgNum > highestArgIdx {
296 highestArgIdx = verb.ArgNum
297 }
298
293 err := formatAppend(&verb, &buf, a) 299 err := formatAppend(&verb, &buf, a)
294 if err != nil { 300 if err != nil {
295 return buf.String(), err 301 return buf.String(), err
296 } 302 }
297 nextArg = verb.ArgNum + 1 303 nextArg = verb.ArgNum + 1
298 304
299 // line 324 "format_fsm.go" 305 // line 330 "format_fsm.go"
300 } 306 }
301 } 307 }
302 308
@@ -319,22 +325,22 @@ func formatFSM(format string, a []cty.Value) (string, error) {
319 __acts++ 325 __acts++
320 switch _formatfsm_actions[__acts-1] { 326 switch _formatfsm_actions[__acts-1] {
321 case 2: 327 case 2:
322 // line 42 "format_fsm.rl" 328 // line 44 "format_fsm.rl"
323 329
324 case 3: 330 case 3:
325 // line 45 "format_fsm.rl" 331 // line 47 "format_fsm.rl"
326 332
327 return buf.String(), fmt.Errorf("invalid format string starting at offset %d", p) 333 return buf.String(), fmt.Errorf("invalid format string starting at offset %d", p)
328 334
329 case 4: 335 case 4:
330 // line 49 "format_fsm.rl" 336 // line 51 "format_fsm.rl"
331 337
332 // We'll try to slurp a whole UTF-8 sequence here, to give the user 338 // We'll try to slurp a whole UTF-8 sequence here, to give the user
333 // better feedback. 339 // better feedback.
334 r, _ := utf8.DecodeRuneInString(data[p:]) 340 r, _ := utf8.DecodeRuneInString(data[p:])
335 return buf.String(), fmt.Errorf("unrecognized format character %q at offset %d", r, p) 341 return buf.String(), fmt.Errorf("unrecognized format character %q at offset %d", r, p)
336 342
337 // line 363 "format_fsm.go" 343 // line 369 "format_fsm.go"
338 } 344 }
339 } 345 }
340 } 346 }
@@ -344,14 +350,24 @@ func formatFSM(format string, a []cty.Value) (string, error) {
344 } 350 }
345 } 351 }
346 352
347 // line 171 "format_fsm.rl" 353 // line 177 "format_fsm.rl"
348 354
349 // If we fall out here without being in a final state then we've 355 // If we fall out here without being in a final state then we've
350 // encountered something that the scanner can't match, which should 356 // encountered something that the scanner can't match, which should
351 // be impossible (the scanner matches all bytes _somehow_) but we'll 357 // be impossible (the scanner matches all bytes _somehow_) but we'll
352 // flag it anyway rather than just losing data from the end. 358 // flag it anyway rather than just losing data from the end.
353 if cs < formatfsm_first_final { 359 if cs < formatfsm_first_final {
354 return buf.String(), fmt.Errorf("extraneous characters beginning at offset %i", p) 360 return buf.String(), fmt.Errorf("extraneous characters beginning at offset %d", p)
361 }
362
363 if highestArgIdx < len(a) {
364 // Extraneous args are an error, to more easily detect mistakes
365 firstBad := highestArgIdx + 1
366 if highestArgIdx == 0 {
367 // Custom error message for this case
368 return buf.String(), function.NewArgErrorf(firstBad, "too many arguments; no verbs in format string")
369 }
370 return buf.String(), function.NewArgErrorf(firstBad, "too many arguments; only %d used by format string", highestArgIdx)
355 } 371 }
356 372
357 return buf.String(), nil 373 return buf.String(), nil
diff --git a/vendor/github.com/zclconf/go-cty/cty/function/stdlib/format_fsm.rl b/vendor/github.com/zclconf/go-cty/cty/function/stdlib/format_fsm.rl
index 85d43bb..3c642d9 100644
--- a/vendor/github.com/zclconf/go-cty/cty/function/stdlib/format_fsm.rl
+++ b/vendor/github.com/zclconf/go-cty/cty/function/stdlib/format_fsm.rl
@@ -12,6 +12,7 @@ import (
12 "unicode/utf8" 12 "unicode/utf8"
13 13
14 "github.com/zclconf/go-cty/cty" 14 "github.com/zclconf/go-cty/cty"
15 "github.com/zclconf/go-cty/cty/function"
15) 16)
16 17
17%%{ 18%%{
@@ -23,6 +24,7 @@ func formatFSM(format string, a []cty.Value) (string, error) {
23 data := format 24 data := format
24 nextArg := 1 // arg numbers are 1-based 25 nextArg := 1 // arg numbers are 1-based
25 var verb formatVerb 26 var verb formatVerb
27 highestArgIdx := 0 // zero means "none", since arg numbers are 1-based
26 28
27 %%{ 29 %%{
28 30
@@ -102,6 +104,10 @@ func formatFSM(format string, a []cty.Value) (string, error) {
102 verb.Raw = data[ts:te] 104 verb.Raw = data[ts:te]
103 verb.Offset = ts 105 verb.Offset = ts
104 106
107 if verb.ArgNum > highestArgIdx {
108 highestArgIdx = verb.ArgNum
109 }
110
105 err := formatAppend(&verb, &buf, a) 111 err := formatAppend(&verb, &buf, a)
106 if err != nil { 112 if err != nil {
107 return buf.String(), err 113 return buf.String(), err
@@ -175,7 +181,17 @@ func formatFSM(format string, a []cty.Value) (string, error) {
175 // be impossible (the scanner matches all bytes _somehow_) but we'll 181 // be impossible (the scanner matches all bytes _somehow_) but we'll
176 // flag it anyway rather than just losing data from the end. 182 // flag it anyway rather than just losing data from the end.
177 if cs < formatfsm_first_final { 183 if cs < formatfsm_first_final {
178 return buf.String(), fmt.Errorf("extraneous characters beginning at offset %i", p) 184 return buf.String(), fmt.Errorf("extraneous characters beginning at offset %d", p)
185 }
186
187 if highestArgIdx < len(a) {
188 // Extraneous args are an error, to more easily detect mistakes
189 firstBad := highestArgIdx+1
190 if highestArgIdx == 0 {
191 // Custom error message for this case
192 return buf.String(), function.NewArgErrorf(firstBad, "too many arguments; no verbs in format string")
193 }
194 return buf.String(), function.NewArgErrorf(firstBad, "too many arguments; only %d used by format string", highestArgIdx)
179 } 195 }
180 196
181 return buf.String(), nil 197 return buf.String(), nil
diff --git a/vendor/github.com/zclconf/go-cty/cty/function/stdlib/regexp.go b/vendor/github.com/zclconf/go-cty/cty/function/stdlib/regexp.go
new file mode 100644
index 0000000..2dd6348
--- /dev/null
+++ b/vendor/github.com/zclconf/go-cty/cty/function/stdlib/regexp.go
@@ -0,0 +1,233 @@
1package stdlib
2
3import (
4 "fmt"
5 "regexp"
6 resyntax "regexp/syntax"
7
8 "github.com/zclconf/go-cty/cty"
9 "github.com/zclconf/go-cty/cty/function"
10)
11
12var RegexFunc = function.New(&function.Spec{
13 Params: []function.Parameter{
14 {
15 Name: "pattern",
16 Type: cty.String,
17 },
18 {
19 Name: "string",
20 Type: cty.String,
21 },
22 },
23 Type: func(args []cty.Value) (cty.Type, error) {
24 if !args[0].IsKnown() {
25 // We can't predict our type without seeing our pattern
26 return cty.DynamicPseudoType, nil
27 }
28
29 retTy, err := regexPatternResultType(args[0].AsString())
30 if err != nil {
31 err = function.NewArgError(0, err)
32 }
33 return retTy, err
34 },
35 Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
36 if retType == cty.DynamicPseudoType {
37 return cty.DynamicVal, nil
38 }
39
40 re, err := regexp.Compile(args[0].AsString())
41 if err != nil {
42 // Should never happen, since we checked this in the Type function above.
43 return cty.NilVal, function.NewArgErrorf(0, "error parsing pattern: %s", err)
44 }
45 str := args[1].AsString()
46
47 captureIdxs := re.FindStringSubmatchIndex(str)
48 if captureIdxs == nil {
49 return cty.NilVal, fmt.Errorf("pattern did not match any part of the given string")
50 }
51
52 return regexPatternResult(re, str, captureIdxs, retType), nil
53 },
54})
55
56var RegexAllFunc = function.New(&function.Spec{
57 Params: []function.Parameter{
58 {
59 Name: "pattern",
60 Type: cty.String,
61 },
62 {
63 Name: "string",
64 Type: cty.String,
65 },
66 },
67 Type: func(args []cty.Value) (cty.Type, error) {
68 if !args[0].IsKnown() {
69 // We can't predict our type without seeing our pattern,
70 // but we do know it'll always be a list of something.
71 return cty.List(cty.DynamicPseudoType), nil
72 }
73
74 retTy, err := regexPatternResultType(args[0].AsString())
75 if err != nil {
76 err = function.NewArgError(0, err)
77 }
78 return cty.List(retTy), err
79 },
80 Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
81 ety := retType.ElementType()
82 if ety == cty.DynamicPseudoType {
83 return cty.DynamicVal, nil
84 }
85
86 re, err := regexp.Compile(args[0].AsString())
87 if err != nil {
88 // Should never happen, since we checked this in the Type function above.
89 return cty.NilVal, function.NewArgErrorf(0, "error parsing pattern: %s", err)
90 }
91 str := args[1].AsString()
92
93 captureIdxsEach := re.FindAllStringSubmatchIndex(str, -1)
94 if len(captureIdxsEach) == 0 {
95 return cty.ListValEmpty(ety), nil
96 }
97
98 elems := make([]cty.Value, len(captureIdxsEach))
99 for i, captureIdxs := range captureIdxsEach {
100 elems[i] = regexPatternResult(re, str, captureIdxs, ety)
101 }
102 return cty.ListVal(elems), nil
103 },
104})
105
106// Regex is a function that extracts one or more substrings from a given
107// string by applying a regular expression pattern, describing the first
108// match.
109//
110// The return type depends on the composition of the capture groups (if any)
111// in the pattern:
112//
113// - If there are no capture groups at all, the result is a single string
114// representing the entire matched pattern.
115// - If all of the capture groups are named, the result is an object whose
116// keys are the named groups and whose values are their sub-matches, or
117// null if a particular sub-group was inside another group that didn't
118// match.
119// - If none of the capture groups are named, the result is a tuple whose
120// elements are the sub-groups in order and whose values are their
121// sub-matches, or null if a particular sub-group was inside another group
122// that didn't match.
123// - It is invalid to use both named and un-named capture groups together in
124// the same pattern.
125//
126// If the pattern doesn't match, this function returns an error. To test for
127// a match, call RegexAll and check if the length of the result is greater
128// than zero.
129func Regex(pattern, str cty.Value) (cty.Value, error) {
130 return RegexFunc.Call([]cty.Value{pattern, str})
131}
132
133// RegexAll is similar to Regex but it finds all of the non-overlapping matches
134// in the given string and returns a list of them.
135//
136// The result type is always a list, whose element type is deduced from the
137// pattern in the same way as the return type for Regex is decided.
138//
139// If the pattern doesn't match at all, this function returns an empty list.
140func RegexAll(pattern, str cty.Value) (cty.Value, error) {
141 return RegexAllFunc.Call([]cty.Value{pattern, str})
142}
143
144// regexPatternResultType parses the given regular expression pattern and
145// returns the structural type that would be returned to represent its
146// capture groups.
147//
148// Returns an error if parsing fails or if the pattern uses a mixture of
149// named and unnamed capture groups, which is not permitted.
150func regexPatternResultType(pattern string) (cty.Type, error) {
151 re, rawErr := regexp.Compile(pattern)
152 switch err := rawErr.(type) {
153 case *resyntax.Error:
154 return cty.NilType, fmt.Errorf("invalid regexp pattern: %s in %s", err.Code, err.Expr)
155 case error:
156 // Should never happen, since all regexp compile errors should
157 // be resyntax.Error, but just in case...
158 return cty.NilType, fmt.Errorf("error parsing pattern: %s", err)
159 }
160
161 allNames := re.SubexpNames()[1:]
162 var names []string
163 unnamed := 0
164 for _, name := range allNames {
165 if name == "" {
166 unnamed++
167 } else {
168 if names == nil {
169 names = make([]string, 0, len(allNames))
170 }
171 names = append(names, name)
172 }
173 }
174 switch {
175 case unnamed == 0 && len(names) == 0:
176 // If there are no capture groups at all then we'll return just a
177 // single string for the whole match.
178 return cty.String, nil
179 case unnamed > 0 && len(names) > 0:
180 return cty.NilType, fmt.Errorf("invalid regexp pattern: cannot mix both named and unnamed capture groups")
181 case unnamed > 0:
182 // For unnamed captures, we return a tuple of them all in order.
183 etys := make([]cty.Type, unnamed)
184 for i := range etys {
185 etys[i] = cty.String
186 }
187 return cty.Tuple(etys), nil
188 default:
189 // For named captures, we return an object using the capture names
190 // as keys.
191 atys := make(map[string]cty.Type, len(names))
192 for _, name := range names {
193 atys[name] = cty.String
194 }
195 return cty.Object(atys), nil
196 }
197}
198
199func regexPatternResult(re *regexp.Regexp, str string, captureIdxs []int, retType cty.Type) cty.Value {
200 switch {
201 case retType == cty.String:
202 start, end := captureIdxs[0], captureIdxs[1]
203 return cty.StringVal(str[start:end])
204 case retType.IsTupleType():
205 captureIdxs = captureIdxs[2:] // index 0 is the whole pattern span, which we ignore by skipping one pair
206 vals := make([]cty.Value, len(captureIdxs)/2)
207 for i := range vals {
208 start, end := captureIdxs[i*2], captureIdxs[i*2+1]
209 if start < 0 || end < 0 {
210 vals[i] = cty.NullVal(cty.String) // Did not match anything because containing group didn't match
211 continue
212 }
213 vals[i] = cty.StringVal(str[start:end])
214 }
215 return cty.TupleVal(vals)
216 case retType.IsObjectType():
217 captureIdxs = captureIdxs[2:] // index 0 is the whole pattern span, which we ignore by skipping one pair
218 vals := make(map[string]cty.Value, len(captureIdxs)/2)
219 names := re.SubexpNames()[1:]
220 for i, name := range names {
221 start, end := captureIdxs[i*2], captureIdxs[i*2+1]
222 if start < 0 || end < 0 {
223 vals[name] = cty.NullVal(cty.String) // Did not match anything because containing group didn't match
224 continue
225 }
226 vals[name] = cty.StringVal(str[start:end])
227 }
228 return cty.ObjectVal(vals)
229 default:
230 // Should never happen
231 panic(fmt.Sprintf("invalid return type %#v", retType))
232 }
233}
diff --git a/vendor/github.com/zclconf/go-cty/cty/function/stdlib/sequence.go b/vendor/github.com/zclconf/go-cty/cty/function/stdlib/sequence.go
index e2c77c5..d3cc341 100644
--- a/vendor/github.com/zclconf/go-cty/cty/function/stdlib/sequence.go
+++ b/vendor/github.com/zclconf/go-cty/cty/function/stdlib/sequence.go
@@ -119,6 +119,75 @@ var ConcatFunc = function.New(&function.Spec{
119 }, 119 },
120}) 120})
121 121
122var RangeFunc = function.New(&function.Spec{
123 VarParam: &function.Parameter{
124 Name: "params",
125 Type: cty.Number,
126 },
127 Type: function.StaticReturnType(cty.List(cty.Number)),
128 Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
129 var start, end, step cty.Value
130 switch len(args) {
131 case 1:
132 if args[0].LessThan(cty.Zero).True() {
133 start, end, step = cty.Zero, args[0], cty.NumberIntVal(-1)
134 } else {
135 start, end, step = cty.Zero, args[0], cty.NumberIntVal(1)
136 }
137 case 2:
138 if args[1].LessThan(args[0]).True() {
139 start, end, step = args[0], args[1], cty.NumberIntVal(-1)
140 } else {
141 start, end, step = args[0], args[1], cty.NumberIntVal(1)
142 }
143 case 3:
144 start, end, step = args[0], args[1], args[2]
145 default:
146 return cty.NilVal, fmt.Errorf("must have one, two, or three arguments")
147 }
148
149 var vals []cty.Value
150
151 if step == cty.Zero {
152 return cty.NilVal, function.NewArgErrorf(2, "step must not be zero")
153 }
154 down := step.LessThan(cty.Zero).True()
155
156 if down {
157 if end.GreaterThan(start).True() {
158 return cty.NilVal, function.NewArgErrorf(1, "end must be less than start when step is negative")
159 }
160 } else {
161 if end.LessThan(start).True() {
162 return cty.NilVal, function.NewArgErrorf(1, "end must be greater than start when step is positive")
163 }
164 }
165
166 num := start
167 for {
168 if down {
169 if num.LessThanOrEqualTo(end).True() {
170 break
171 }
172 } else {
173 if num.GreaterThanOrEqualTo(end).True() {
174 break
175 }
176 }
177 if len(vals) >= 1024 {
178 // Artificial limit to prevent bad arguments from consuming huge amounts of memory
179 return cty.NilVal, fmt.Errorf("more than 1024 values were generated; either decrease the difference between start and end or use a smaller step")
180 }
181 vals = append(vals, num)
182 num = num.Add(step)
183 }
184 if len(vals) == 0 {
185 return cty.ListValEmpty(cty.Number), nil
186 }
187 return cty.ListVal(vals), nil
188 },
189})
190
122// Concat takes one or more sequences (lists or tuples) and returns the single 191// Concat takes one or more sequences (lists or tuples) and returns the single
123// sequence that results from concatenating them together in order. 192// sequence that results from concatenating them together in order.
124// 193//
@@ -128,3 +197,22 @@ var ConcatFunc = function.New(&function.Spec{
128func Concat(seqs ...cty.Value) (cty.Value, error) { 197func Concat(seqs ...cty.Value) (cty.Value, error) {
129 return ConcatFunc.Call(seqs) 198 return ConcatFunc.Call(seqs)
130} 199}
200
201// Range creates a list of numbers by starting from the given starting value,
202// then adding the given step value until the result is greater than or
203// equal to the given stopping value. Each intermediate result becomes an
204// element in the resulting list.
205//
206// When all three parameters are set, the order is (start, end, step). If
207// only two parameters are set, they are the start and end respectively and
208// step defaults to 1. If only one argument is set, it gives the end value
209// with start defaulting to 0 and step defaulting to 1.
210//
211// Because the resulting list must be fully buffered in memory, there is an
212// artificial cap of 1024 elements, after which this function will return
213// an error to avoid consuming unbounded amounts of memory. The Range function
214// is primarily intended for creating small lists of indices to iterate over,
215// so there should be no reason to generate huge lists with it.
216func Range(params ...cty.Value) (cty.Value, error) {
217 return RangeFunc.Call(params)
218}