cddl 0.1.7 → 0.1.8
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/data/cddl.abnf +5 -2
- data/lib/cddl.rb +91 -4
- data/test-data/jcr-ex.cddl +42 -0
- data/test/test-cddl.rb +82 -11
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 069ab5627679f8b9c644f6469eff2a3760c4c911
|
4
|
+
data.tar.gz: 39c18606d5c35934d4933ff96c444a7f685f7003
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 65ff54e705aa476af42d7157cfa87120678b59d6c8177d86a6552abd5c4ee135531b8c17dcb078c34fed3a773c67aaddc6e30c645e9c40af22bb1fca6c6d1a08
|
7
|
+
data.tar.gz: 32049a27a9a6a2ca7080a7d9bffde7fa7c3e2f0e88eaac030fb9ea97b87e0bd0b5844d660ec730ca321665f96d01eb68af78f119c809974178bde444bb7b8638
|
data/cddl.gemspec
CHANGED
data/data/cddl.abnf
CHANGED
@@ -7,7 +7,7 @@ groupname = id
|
|
7
7
|
|
8
8
|
type = type1 S *("/" S type1 S)
|
9
9
|
|
10
|
-
type1 = type2 [rangeop type2]
|
10
|
+
type1 = type2 [S (rangeop / annotation) S type2]
|
11
11
|
/ "#" "6" ["." uint] "(" S type S ")" ; note no space!
|
12
12
|
/ "#" DIGIT ["." uint] ; major/ai
|
13
13
|
/ "#" ; any
|
@@ -22,6 +22,8 @@ type2 = value
|
|
22
22
|
|
23
23
|
rangeop = "..." / ".."
|
24
24
|
|
25
|
+
annotation = "." id
|
26
|
+
|
25
27
|
group = "(" S *grpent S ")"
|
26
28
|
/ *grpent
|
27
29
|
|
@@ -57,8 +59,9 @@ string = %x22 *SCHAR %x22
|
|
57
59
|
SCHAR = %x20-21 / %x23-7E / SESC
|
58
60
|
SESC = "\" %x20-7E
|
59
61
|
|
60
|
-
id =
|
62
|
+
id = EALPHA *(*("-" / ".") (EALPHA / DIGIT))
|
61
63
|
ALPHA = %x41-5A / %x61-7A
|
64
|
+
EALPHA = %x41-5A / %x61-7A / "@" / "_"
|
62
65
|
DIGIT = %x30-39
|
63
66
|
DIGIT1 = %x31-39
|
64
67
|
S = *WS
|
data/lib/cddl.rb
CHANGED
@@ -37,6 +37,12 @@ module CDDL
|
|
37
37
|
@abnf.parse_results
|
38
38
|
end
|
39
39
|
|
40
|
+
def strip_nodes(n)
|
41
|
+
[n[0], *n[1..-1].map {|e|
|
42
|
+
e._strip
|
43
|
+
}]
|
44
|
+
end
|
45
|
+
|
40
46
|
def rules
|
41
47
|
@rules = {}
|
42
48
|
ast.each :rule do |rule|
|
@@ -49,7 +55,15 @@ module CDDL
|
|
49
55
|
fail "Huh?"
|
50
56
|
end
|
51
57
|
n = rulename.to_s
|
52
|
-
|
58
|
+
if @rules[n]
|
59
|
+
a = strip_nodes(rule_ast).inspect
|
60
|
+
b = strip_nodes(@rules[n]).inspect
|
61
|
+
if a == b
|
62
|
+
warn "*** Warning: Identical redefinition of #{n} as #{a}"
|
63
|
+
else
|
64
|
+
fail "Duplicate rule definition #{n} as #{b} (was #{a})"
|
65
|
+
end
|
66
|
+
end
|
53
67
|
@rules[n] = rule_ast
|
54
68
|
end
|
55
69
|
# pp @rules
|
@@ -102,7 +116,7 @@ module CDDL
|
|
102
116
|
when :prim
|
103
117
|
case where[1]
|
104
118
|
when nil
|
105
|
-
gen_word
|
119
|
+
gen_word # XXX: maybe always returning a string is confusing
|
106
120
|
when 0
|
107
121
|
rand(4711)
|
108
122
|
when 1
|
@@ -131,6 +145,42 @@ module CDDL
|
|
131
145
|
else
|
132
146
|
fail "Can't generate prim #{where[1]}"
|
133
147
|
end
|
148
|
+
when :anno
|
149
|
+
target = where[2]
|
150
|
+
control = where[3]
|
151
|
+
case where[1]
|
152
|
+
when :size
|
153
|
+
should_be_int = generate(control)
|
154
|
+
unless target == [:prim, 2] && Integer === should_be_int
|
155
|
+
fail "Don't know yet how to generate #{where}"
|
156
|
+
end
|
157
|
+
Random.new.bytes(should_be_int)
|
158
|
+
when :bits
|
159
|
+
set_of_bits = Array.new(10) { generate(control) } # XXX: ten?
|
160
|
+
p set_of_bits
|
161
|
+
unless target == [:prim, 2] && set_of_bits.all? {|x| Integer === x && x >= 0 }
|
162
|
+
fail "Don't know yet how to generate #{where}"
|
163
|
+
end
|
164
|
+
s = String.new
|
165
|
+
set_of_bits.each do |i|
|
166
|
+
n = i >> 3
|
167
|
+
bit = 1 << (i & 7)
|
168
|
+
if v = s.getbyte(n)
|
169
|
+
s.setbyte(n, v | bit)
|
170
|
+
else
|
171
|
+
s << "\0" * (s.size - n) << bit.chr(Encoding::BINARY)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
s
|
175
|
+
when :regexp
|
176
|
+
regexp = generate(control)
|
177
|
+
unless target == [:prim, 3] && String === regexp
|
178
|
+
fail "Don't know yet how to generate #{where}"
|
179
|
+
end
|
180
|
+
"regexp /#{regexp}/ punt for now"
|
181
|
+
else
|
182
|
+
fail "Don't know yet how to generate from #{where}"
|
183
|
+
end
|
134
184
|
else
|
135
185
|
fail "Don't know how to generate from #{where[0]}"
|
136
186
|
end
|
@@ -255,6 +305,35 @@ module CDDL
|
|
255
305
|
d == v
|
256
306
|
when :range
|
257
307
|
where[2] === d && where[1].include?(d)
|
308
|
+
when :anno
|
309
|
+
target = where[2]
|
310
|
+
if validate1(d, target)
|
311
|
+
control = where[3]
|
312
|
+
case where[1]
|
313
|
+
when :size
|
314
|
+
validate1(d.bytesize, control)
|
315
|
+
when :bits
|
316
|
+
if String === d
|
317
|
+
d.each_byte.with_index.all? { |b, i|
|
318
|
+
bit = i << 3
|
319
|
+
8.times.all? { |nb|
|
320
|
+
b[nb] == 0 || validate1(bit+nb, control)
|
321
|
+
}
|
322
|
+
}
|
323
|
+
end
|
324
|
+
when :regexp
|
325
|
+
if String === d
|
326
|
+
ok, v, vt = extract_value(control)
|
327
|
+
if ok && vt == String
|
328
|
+
re = Regexp.new("\\A#{v}\\z")
|
329
|
+
pp re
|
330
|
+
d.match(re)
|
331
|
+
end
|
332
|
+
end
|
333
|
+
else
|
334
|
+
fail "Don't know yet how to generate from #{where}"
|
335
|
+
end
|
336
|
+
end
|
258
337
|
when :prim
|
259
338
|
# warn "validate prim WI #{where.inspect} #{d.inspect}"
|
260
339
|
case where[1]
|
@@ -343,7 +422,7 @@ module CDDL
|
|
343
422
|
if t[0] == :grpent && (@insides.last != :array || occ == [1, 1])
|
344
423
|
# go through the members here and multiply the occs
|
345
424
|
t1 = t[1..-1].flatten(1)
|
346
|
-
t1.flat_map {|t2|
|
425
|
+
t1.flat_map {|t2|
|
347
426
|
if t2[0] == :member
|
348
427
|
[t2]
|
349
428
|
else
|
@@ -429,13 +508,15 @@ module CDDL
|
|
429
508
|
|
430
509
|
BRACE = {"{" => :map, "[" => :array}
|
431
510
|
RANGE_EXCLUDE_END = {".." => false, "..." => true}
|
511
|
+
SUPPORTED_ANNOTATIONS = [:bits, :size, :regexp]
|
432
512
|
|
433
513
|
def type1(n, canbegroup = false)
|
434
514
|
# puts "NVALUE #{n.value.inspect}"
|
435
515
|
if v = n.type2
|
516
|
+
ch = n.children(:type2)
|
436
517
|
if ro = n.rangeop
|
437
518
|
cats = []
|
438
|
-
[:range, Range.new(*
|
519
|
+
[:range, Range.new(*ch.map {|l|
|
439
520
|
ok, val, cat = extract_value(type2(l))
|
440
521
|
fail "Can't have range with #{l}" unless ok
|
441
522
|
# XXX really should be checking type coherence of range
|
@@ -443,6 +524,12 @@ module CDDL
|
|
443
524
|
val
|
444
525
|
}, RANGE_EXCLUDE_END[ro.to_s]),
|
445
526
|
cats[0] == cats[1] ? cats[0] : fail("Incompatible range #{cats}")]
|
527
|
+
elsif anno = n.annotation
|
528
|
+
annotyp = anno.id.to_s.intern
|
529
|
+
unless SUPPORTED_ANNOTATIONS.include?(annotyp)
|
530
|
+
fail "Unsupported annotation .#{annotyp}"
|
531
|
+
end
|
532
|
+
[:anno, annotyp, *ch.map {|t| type2(t)}]
|
446
533
|
else
|
447
534
|
type2(v, canbegroup)
|
448
535
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
root = nameserver / entity ; just to root things here
|
2
|
+
|
3
|
+
nameserver = {
|
4
|
+
name: fqdn,
|
5
|
+
ipAddresses: [* ipaddress],
|
6
|
+
common,
|
7
|
+
}
|
8
|
+
|
9
|
+
entity = {
|
10
|
+
names: [* string],
|
11
|
+
roles: [* string],
|
12
|
+
postalAddress: [* string],
|
13
|
+
emails: [* email],
|
14
|
+
phones: {
|
15
|
+
office: [* phone],
|
16
|
+
fax: [* phone],
|
17
|
+
mobile: [* phone],
|
18
|
+
},
|
19
|
+
common,
|
20
|
+
}
|
21
|
+
|
22
|
+
common = (
|
23
|
+
handle: string,
|
24
|
+
status: [* string],
|
25
|
+
remarks: [* string],
|
26
|
+
uris: [* { type: string, "uri": uri }],
|
27
|
+
port43: fqdn,
|
28
|
+
sponsoredBy: string,
|
29
|
+
resoldBy: string,
|
30
|
+
registrationBy: string,
|
31
|
+
registrationDate: tdate,
|
32
|
+
lastChangedDate: tdate,
|
33
|
+
lastChangedBy: string,
|
34
|
+
)
|
35
|
+
|
36
|
+
string = tstr
|
37
|
+
email = tstr
|
38
|
+
phone = tstr
|
39
|
+
fqdn = tstr
|
40
|
+
ipaddress = ip4 / ip6
|
41
|
+
ip4 = bstr ; could pull a #2.4 here, but don't
|
42
|
+
ip6 = bstr ; could pull a #2.16 here, but don't
|
data/test/test-cddl.rb
CHANGED
@@ -190,7 +190,7 @@ HERE
|
|
190
190
|
assert parser.validate([1, 2])
|
191
191
|
end
|
192
192
|
|
193
|
-
|
193
|
+
|
194
194
|
def test_validate_not_unknown_key_paren
|
195
195
|
# $debug_ast = true
|
196
196
|
parser = CDDL::Parser.new <<HERE
|
@@ -313,7 +313,7 @@ HERE
|
|
313
313
|
# pp parser.rules
|
314
314
|
# puts "APR:"
|
315
315
|
# pp parser.apr
|
316
|
-
|
316
|
+
assert_includes [[1, 2, 1, 2], [1, 2, 1, 2, 1, 2]], parser.generate
|
317
317
|
refute parser.validate([], false)
|
318
318
|
refute parser.validate([1], false)
|
319
319
|
refute parser.validate([1, 2], false)
|
@@ -337,7 +337,7 @@ HERE
|
|
337
337
|
# pp parser.rules
|
338
338
|
# puts "APR:"
|
339
339
|
# pp parser.apr
|
340
|
-
|
340
|
+
assert_includes [[1, 2, 1, 2], [1, 2, 1, 2, 1, 2]], parser.generate
|
341
341
|
refute parser.validate([], false)
|
342
342
|
refute parser.validate([1], false)
|
343
343
|
refute parser.validate([1, 2], false)
|
@@ -369,8 +369,8 @@ f16: float16
|
|
369
369
|
}
|
370
370
|
beer = 3.14 / 6.28
|
371
371
|
HERE
|
372
|
-
pp parser.rules
|
373
|
-
pp parser.generate
|
372
|
+
# pp parser.rules
|
373
|
+
# pp parser.generate
|
374
374
|
refute parser.validate({}, false)
|
375
375
|
assert parser.validate({"f16" => 1.5, "foo" => 1, "f64" => 1.1, "bar" => 3.14})
|
376
376
|
assert parser.validate({"f16" => 1.5, "foo" => 1, "f64" => 1.1, "bar" => 6.28})
|
@@ -403,7 +403,7 @@ HERE
|
|
403
403
|
|
404
404
|
def test_nested_group_many1
|
405
405
|
parser = CDDL::Parser.new <<HERE
|
406
|
-
foo = {* bar}
|
406
|
+
foo = {* bar}
|
407
407
|
bar = (* b: 1)
|
408
408
|
HERE
|
409
409
|
assert_equal [:type1, [:map, [:member, 0, CDDL::MANY, [:string, "b"], [:int, 1]]]], parser.rules
|
@@ -411,7 +411,7 @@ HERE
|
|
411
411
|
|
412
412
|
def test_nested_group_many2
|
413
413
|
parser = CDDL::Parser.new <<HERE
|
414
|
-
foo = {* bar}
|
414
|
+
foo = {* bar}
|
415
415
|
bar = (b: 1)
|
416
416
|
HERE
|
417
417
|
assert_equal [:type1, [:map, [:member, 0, CDDL::MANY, [:string, "b"], [:int, 1]]]], parser.rules
|
@@ -419,7 +419,7 @@ HERE
|
|
419
419
|
|
420
420
|
def test_nested_group_many3
|
421
421
|
parser = CDDL::Parser.new <<HERE
|
422
|
-
foo = {* bar}
|
422
|
+
foo = {* bar}
|
423
423
|
bar = (4*6 b: 1)
|
424
424
|
HERE
|
425
425
|
assert_equal [:type1, [:map, [:member, 0, CDDL::MANY, [:string, "b"], [:int, 1]]]], parser.rules
|
@@ -449,7 +449,7 @@ HERE
|
|
449
449
|
}
|
450
450
|
assert parser.validate(0)
|
451
451
|
assert parser.validate(7)
|
452
|
-
refute parser.validate(7.0)
|
452
|
+
refute parser.validate(7.0, false)
|
453
453
|
assert parser.validate(12)
|
454
454
|
refute parser.validate(-1, false)
|
455
455
|
refute parser.validate(13, false)
|
@@ -460,14 +460,14 @@ HERE
|
|
460
460
|
color = 0.5..max
|
461
461
|
max = 12.5
|
462
462
|
HERE
|
463
|
-
pp parser.rules
|
463
|
+
# pp parser.rules
|
464
464
|
10.times {
|
465
465
|
assert parser.generate.between?(0.5, 12.5)
|
466
466
|
}
|
467
467
|
refute parser.validate(0.0, false)
|
468
468
|
assert parser.validate(0.5)
|
469
469
|
assert parser.validate(7.0)
|
470
|
-
refute parser.validate(7)
|
470
|
+
refute parser.validate(7, false)
|
471
471
|
assert parser.validate(12.0)
|
472
472
|
assert parser.validate(12.5)
|
473
473
|
refute parser.validate(-1.0, false)
|
@@ -589,5 +589,76 @@ HERE
|
|
589
589
|
assert_raise { parser.validate({}) }
|
590
590
|
end
|
591
591
|
|
592
|
+
def test_identical_redefinition
|
593
|
+
parser = CDDL::Parser.new <<HERE
|
594
|
+
test =
|
595
|
+
"Cephalotaxus Germanism dovekey Istiophorus" / foo
|
596
|
+
test = "Cephalotaxus Germanism dovekey Istiophorus"
|
597
|
+
/ foo
|
598
|
+
foo = 1
|
599
|
+
HERE
|
600
|
+
pp parser.rules
|
601
|
+
end
|
602
|
+
|
603
|
+
def test_bad_redefinition
|
604
|
+
parser = CDDL::Parser.new <<HERE
|
605
|
+
test =
|
606
|
+
"Cephalotaxus Germanism dovekey Istiophorus" / foo
|
607
|
+
test = "Cephalotaxus Germanism dovekey Istiophorus"
|
608
|
+
/ fob
|
609
|
+
foo = 1
|
610
|
+
fob = 1
|
611
|
+
HERE
|
612
|
+
assert_raise {
|
613
|
+
pp parser.rules
|
614
|
+
}
|
615
|
+
end
|
616
|
+
|
617
|
+
def test_bad_annotation
|
618
|
+
parser = CDDL::Parser.new <<HERE
|
619
|
+
test = int .foo 3
|
620
|
+
HERE
|
621
|
+
assert_raise {
|
622
|
+
pp parser.rules
|
623
|
+
}
|
624
|
+
end
|
625
|
+
|
626
|
+
def test_size_annotation
|
627
|
+
parser = CDDL::Parser.new <<HERE
|
628
|
+
test = bstr .size 3
|
629
|
+
HERE
|
630
|
+
pp parser.rules
|
631
|
+
gen = parser.generate
|
632
|
+
assert String === gen
|
633
|
+
assert gen.bytesize == 3
|
634
|
+
pp gen
|
635
|
+
assert parser.validate(gen)
|
636
|
+
end
|
637
|
+
|
638
|
+
def test_bits_annotation
|
639
|
+
parser = CDDL::Parser.new <<HERE
|
640
|
+
test = bstr .bits (1 / 3 / 5)
|
641
|
+
HERE
|
642
|
+
pp parser.rules
|
643
|
+
gen = parser.generate
|
644
|
+
assert String === gen
|
645
|
+
pp gen # should mostly be "*"
|
646
|
+
assert parser.validate(gen)
|
647
|
+
end
|
648
|
+
|
649
|
+
def test_regexp_annotation
|
650
|
+
parser = CDDL::Parser.new <<HERE
|
651
|
+
test = tstr .regexp "reg.*"
|
652
|
+
HERE
|
653
|
+
pp parser.rules
|
654
|
+
gen = parser.generate
|
655
|
+
assert String === gen
|
656
|
+
pp gen
|
657
|
+
assert parser.validate(gen)
|
658
|
+
assert parser.validate("reg")
|
659
|
+
assert parser.validate("regfoo")
|
660
|
+
refute parser.validate("foo", false)
|
661
|
+
refute parser.validate("re", false)
|
662
|
+
end
|
592
663
|
|
593
664
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cddl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Carsten Bormann
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-03-
|
11
|
+
date: 2015-03-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cbor-diag
|
@@ -67,6 +67,7 @@ files:
|
|
67
67
|
- test-data/7071-concise.cddl
|
68
68
|
- test-data/7071-verbose.cddl
|
69
69
|
- test-data/basic_syntax_example.cddl
|
70
|
+
- test-data/jcr-ex.cddl
|
70
71
|
- test-data/minimal.cddl
|
71
72
|
- test-data/reused_named_group.cddl
|
72
73
|
- test-data/structure.cddl
|