cddl 0.4.0 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/cddl.gemspec +1 -1
- data/lib/cddl.rb +47 -15
- data/test/test-cddl.rb +19 -0
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d81421c45b8589d98a0bee597ebf58684b6dc47d
|
4
|
+
data.tar.gz: 2c43ce26e9ec1061a91ffc078eb797293e6e861c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a59f236c132f7d3c4c20b20275270a304873abe3a0a527cd923a84d683ab953d59a65fa006f7de0c81de45c0d175bb86dcbb7abc680aa5f83e7753464d0dc8d6
|
7
|
+
data.tar.gz: 2724e39b65ff8d6b2de65845ae67a713276fd99743625f2745bc4d6a6c0433ae43f736d47e1741f5e4df936c5102f112e675e541cffa3991a98abb54e93c9b67
|
data/cddl.gemspec
CHANGED
data/lib/cddl.rb
CHANGED
@@ -14,6 +14,8 @@ module CDDL
|
|
14
14
|
|
15
15
|
MANY = Float::INFINITY
|
16
16
|
|
17
|
+
MAX_RECURSE = 32 # XXX
|
18
|
+
|
17
19
|
class ParseError < ArgumentError; end
|
18
20
|
|
19
21
|
class Parser
|
@@ -119,14 +121,19 @@ module CDDL
|
|
119
121
|
h[k] = Regexp.new("\\A#{k}\\z")
|
120
122
|
}
|
121
123
|
|
122
|
-
def generate
|
124
|
+
def generate
|
125
|
+
@recursion = 0
|
126
|
+
generate1(rules)
|
127
|
+
end
|
128
|
+
|
129
|
+
def generate1(where, inmap = false)
|
123
130
|
case where[0]
|
124
131
|
when :type1
|
125
|
-
|
132
|
+
generate1(where[rand(where.size-1)+1])
|
126
133
|
when :map
|
127
|
-
Hash[where[1..-1].flat_map {|m|
|
134
|
+
Hash[where[1..-1].flat_map {|m| generate1(m, true)}]
|
128
135
|
when :array, :grpent
|
129
|
-
r = where[1..-1].flat_map {|m|
|
136
|
+
r = where[1..-1].flat_map {|m| generate1(m).map{|e| e[1]}}
|
130
137
|
.flat_map {|e| Array === e && e[0] == :grpent ? e[1..-1] : [e]}
|
131
138
|
# nested grpents need to be "unpacked"
|
132
139
|
if where[0] == :grpent
|
@@ -141,8 +148,8 @@ module CDDL
|
|
141
148
|
kr = where[3]
|
142
149
|
vr = where[4]
|
143
150
|
fail "member key not given in map for #{where}" unless kr if inmap
|
144
|
-
Array.new(st) { [ (
|
145
|
-
|
151
|
+
Array.new(st) { [ (generate1(kr) if kr), # XXX: need error in map context
|
152
|
+
generate1(vr)
|
146
153
|
]}
|
147
154
|
when :string, :int, :float
|
148
155
|
where[1]
|
@@ -161,7 +168,7 @@ module CDDL
|
|
161
168
|
when 3
|
162
169
|
gen_word
|
163
170
|
when 6
|
164
|
-
CBOR::Tagged.new(where[2],
|
171
|
+
CBOR::Tagged.new(where[2], generate1(where[3]))
|
165
172
|
when 7
|
166
173
|
case where[2]
|
167
174
|
when nil
|
@@ -185,13 +192,13 @@ module CDDL
|
|
185
192
|
control = where[3]
|
186
193
|
case where[1]
|
187
194
|
when :size
|
188
|
-
should_be_int =
|
195
|
+
should_be_int = generate1(control)
|
189
196
|
unless target == [:prim, 2] && Integer === should_be_int
|
190
197
|
fail "Don't know yet how to generate #{where}"
|
191
198
|
end
|
192
199
|
Random.new.bytes(should_be_int)
|
193
200
|
when :bits
|
194
|
-
set_of_bits = Array.new(10) {
|
201
|
+
set_of_bits = Array.new(10) { generate1(control) } # XXX: ten?
|
195
202
|
# p set_of_bits
|
196
203
|
unless (target == [:prim, 0] || target == [:prim, 2]) &&
|
197
204
|
set_of_bits.all? {|x| Integer === x && x >= 0 }
|
@@ -213,7 +220,7 @@ module CDDL
|
|
213
220
|
end
|
214
221
|
end
|
215
222
|
when :regexp
|
216
|
-
regexp =
|
223
|
+
regexp = generate1(control)
|
217
224
|
unless target == [:prim, 3] && String === regexp
|
218
225
|
fail "Don't know yet how to generate #{where}"
|
219
226
|
end
|
@@ -221,6 +228,17 @@ module CDDL
|
|
221
228
|
else
|
222
229
|
fail "Don't know yet how to generate from #{where}"
|
223
230
|
end
|
231
|
+
when :recurse
|
232
|
+
name = where[1]
|
233
|
+
rule = @stage1[name]
|
234
|
+
if @recursion < MAX_RECURSE
|
235
|
+
@recursion += 1
|
236
|
+
r = generate1(rule)
|
237
|
+
@recursion -= 1
|
238
|
+
r
|
239
|
+
else
|
240
|
+
fail "Deep recursion into #{name}: #{@stage1[name]}, not yet implemented"
|
241
|
+
end
|
224
242
|
else
|
225
243
|
fail "Don't know how to generate from #{where[0]}"
|
226
244
|
end
|
@@ -249,6 +267,7 @@ module CDDL
|
|
249
267
|
end
|
250
268
|
|
251
269
|
def validate(d, warn=true)
|
270
|
+
@recursion = 0
|
252
271
|
result = validate1(d)
|
253
272
|
unless result
|
254
273
|
if warn
|
@@ -416,10 +435,20 @@ module CDDL
|
|
416
435
|
fail
|
417
436
|
end
|
418
437
|
end
|
419
|
-
|
420
438
|
else
|
421
439
|
fail "Can't validate prim #{where[1]} yet"
|
422
440
|
end
|
441
|
+
when :recurse
|
442
|
+
name = where[1]
|
443
|
+
rule = @stage1[name]
|
444
|
+
if @recursion < MAX_RECURSE
|
445
|
+
@recursion += 1
|
446
|
+
r = validate1(d, rule)
|
447
|
+
@recursion -= 1
|
448
|
+
r
|
449
|
+
else
|
450
|
+
fail "Deep recursion into #{name}: #{rule}, not yet implemented"
|
451
|
+
end
|
423
452
|
else
|
424
453
|
# fail where
|
425
454
|
end
|
@@ -455,12 +484,15 @@ module CDDL
|
|
455
484
|
end
|
456
485
|
|
457
486
|
def r_process(n, r, bindings = {})
|
458
|
-
@bindings.push(bindings)
|
459
487
|
t = r[0]
|
460
488
|
# puts "Processing rule #{n} = #{t}"
|
461
|
-
|
462
|
-
|
463
|
-
|
489
|
+
@stage1[n] ||= begin
|
490
|
+
@stage1[n] = [:type1, [:recurse, n]]
|
491
|
+
@bindings.push(bindings)
|
492
|
+
r = [t, *r[1..-1].map {|e| send(t, e)}]
|
493
|
+
@bindings.pop
|
494
|
+
r
|
495
|
+
end
|
464
496
|
end
|
465
497
|
|
466
498
|
def value(n)
|
data/test/test-cddl.rb
CHANGED
@@ -811,4 +811,23 @@ HERE
|
|
811
811
|
}
|
812
812
|
end
|
813
813
|
|
814
|
+
def test_endless_recursion
|
815
|
+
parser = CDDL::Parser.new <<HERE
|
816
|
+
a = a
|
817
|
+
HERE
|
818
|
+
assert_raise { parser.validate(1) }
|
819
|
+
assert_raise { parser.generate }
|
820
|
+
end
|
821
|
+
|
822
|
+
def test_recursion
|
823
|
+
parser = CDDL::Parser.new <<HERE
|
824
|
+
a = [a] / 1
|
825
|
+
HERE
|
826
|
+
10.times {
|
827
|
+
g = parser.generate
|
828
|
+
pp ["recurse-test", g]
|
829
|
+
assert parser.validate(g)
|
830
|
+
}
|
831
|
+
end
|
832
|
+
|
814
833
|
end
|