cddl 0.8.0 → 0.8.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/bin/cddl +7 -3
- data/cddl.gemspec +1 -1
- data/data/cddl.abnf +16 -4
- data/data/prelude.cddl +2 -2
- data/lib/cddl.rb +51 -25
- data/test/test-cddl.rb +87 -19
- data/test-data/7071-concise-cut.cddl +48 -0
- data/test-data/ambig.cddl +2 -0
- data/test-data/badaddr.cddl +1 -0
- data/test-data/dotsize.cddl +7 -0
- data/test-data/grasp-09.cddl +108 -0
- data/test-data/kevin5.cddl +5 -0
- data/test-data/map-group.cddl +13 -0
- data/test-data/mapkey.cddl +2 -0
- data/test-data/toerless0.cddl +14 -0
- data/test-data/toerless1.cddl +11 -0
- metadata +13 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 6c877883cb125426e061f527ba4375c0f021d70dfef060336fe0bb0f5e2ca3d4
|
|
4
|
+
data.tar.gz: 7a3dc4065f3616bf57c229b410782b35140018ecada4418c0ef45056c62aef0b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b3987fbe82e80dddba2f650b1a12941ed6092708297302cf1a78dfe45b20b79d08e85901cb8739b5fc79eab8cde70ca8efb88698f4340da72c722a7a461565c6
|
|
7
|
+
data.tar.gz: 68c35688bac9b30411ee419e171860c463df28c3452bce1741399274e51295b609e0acc8df54e9876037f9d96ba02e369fd9465c2fe7c38bb9682d5ec19018cd
|
data/bin/cddl
CHANGED
|
@@ -7,13 +7,16 @@ require 'json'
|
|
|
7
7
|
|
|
8
8
|
Encoding.default_external = "UTF-8" # wake up, smell the coffee
|
|
9
9
|
|
|
10
|
+
EX_USAGE = 64
|
|
11
|
+
EX_DATAERR = 65
|
|
12
|
+
|
|
10
13
|
def usage
|
|
11
14
|
warn "Usage:"
|
|
12
15
|
warn "#$0 spec.cddl generate [n]"
|
|
13
16
|
warn "#$0 spec.cddl json-generate [n]"
|
|
14
17
|
warn "#$0 spec.cddl validate instance.cbor"
|
|
15
18
|
warn "#$0 spec.cddl validate instance.json"
|
|
16
|
-
exit
|
|
19
|
+
exit EX_USAGE
|
|
17
20
|
end
|
|
18
21
|
|
|
19
22
|
def read_arg(arg)
|
|
@@ -21,7 +24,7 @@ def read_arg(arg)
|
|
|
21
24
|
STDIN.read
|
|
22
25
|
else
|
|
23
26
|
usage unless arg
|
|
24
|
-
File.read(arg)
|
|
27
|
+
File.read(arg, mode: "rb")
|
|
25
28
|
end
|
|
26
29
|
end
|
|
27
30
|
|
|
@@ -86,10 +89,11 @@ begin
|
|
|
86
89
|
# my_pp ann
|
|
87
90
|
instance.cbor_add_annotations_from(ann) rescue nil
|
|
88
91
|
my_diag(instance) if $annotate
|
|
92
|
+
exit 1 unless ann
|
|
89
93
|
else
|
|
90
94
|
usage
|
|
91
95
|
end
|
|
92
96
|
rescue CDDL::ParseError => e
|
|
93
97
|
warn e.message
|
|
94
|
-
exit
|
|
98
|
+
exit EX_DATAERR
|
|
95
99
|
end
|
data/cddl.gemspec
CHANGED
data/data/cddl.abnf
CHANGED
|
@@ -49,11 +49,14 @@ occur = [uint] "*" [uint]
|
|
|
49
49
|
/ "+"
|
|
50
50
|
/ "?"
|
|
51
51
|
|
|
52
|
-
uint =
|
|
53
|
-
/
|
|
52
|
+
uint = DIGIT1 *DIGIT
|
|
53
|
+
/ "0x" 1*HEXDIG
|
|
54
|
+
/ "0b" 1*BINDIG
|
|
55
|
+
/ "0"
|
|
54
56
|
|
|
55
57
|
value = number
|
|
56
|
-
/
|
|
58
|
+
/ text
|
|
59
|
+
/ bytes
|
|
57
60
|
|
|
58
61
|
int = ["-"] uint
|
|
59
62
|
|
|
@@ -62,15 +65,23 @@ number = int ["." fraction] ["e" exponent ]
|
|
|
62
65
|
fraction = 1*DIGIT
|
|
63
66
|
exponent = int
|
|
64
67
|
|
|
65
|
-
|
|
68
|
+
text = %x22 *SCHAR %x22
|
|
66
69
|
SCHAR = %x20-21 / %x23-7E / SESC
|
|
67
70
|
SESC = "\" %x20-7E
|
|
68
71
|
|
|
72
|
+
bytes = [bsqual] %x27 *BCHAR %x27
|
|
73
|
+
BCHAR = %x20-26 / %x28-7E / SESC / CRLF
|
|
74
|
+
bsqual = %x68 ; "h"
|
|
75
|
+
/ %x62.36.34 ; "b64"
|
|
76
|
+
|
|
69
77
|
id = EALPHA *(*("-" / ".") (EALPHA / DIGIT))
|
|
70
78
|
ALPHA = %x41-5A / %x61-7A
|
|
71
79
|
EALPHA = %x41-5A / %x61-7A / "@" / "_" / "$"
|
|
72
80
|
DIGIT = %x30-39
|
|
73
81
|
DIGIT1 = %x31-39
|
|
82
|
+
HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F"
|
|
83
|
+
BINDIG = %x30-31
|
|
84
|
+
|
|
74
85
|
S = *WS
|
|
75
86
|
WS = SP / NL
|
|
76
87
|
SP = %x20
|
|
@@ -78,3 +89,4 @@ NL = COMMENT / CRLF
|
|
|
78
89
|
COMMENT = ";" *(SP / VCHAR) CRLF
|
|
79
90
|
VCHAR = %x21-7E
|
|
80
91
|
CRLF = %x0A / %x0D.0A
|
|
92
|
+
|
data/data/prelude.cddl
CHANGED
|
@@ -22,8 +22,8 @@ unsigned = uint / biguint
|
|
|
22
22
|
decfrac = #6.4([e10: int, m: integer])
|
|
23
23
|
bigfloat = #6.5([e2: int, m: integer])
|
|
24
24
|
eb64url = #6.21(any)
|
|
25
|
-
eb64legacy = #6.
|
|
26
|
-
eb16 = #6.
|
|
25
|
+
eb64legacy = #6.22(any)
|
|
26
|
+
eb16 = #6.23(any)
|
|
27
27
|
encoded-cbor = #6.24(bstr)
|
|
28
28
|
uri = #6.32(tstr)
|
|
29
29
|
b64url = #6.33(tstr)
|
data/lib/cddl.rb
CHANGED
|
@@ -4,6 +4,7 @@ require 'pathname'
|
|
|
4
4
|
require 'cbor-pure' unless defined?(CBOR::Tagged)
|
|
5
5
|
require 'regexp-examples'
|
|
6
6
|
require 'colorize'
|
|
7
|
+
require 'base64'
|
|
7
8
|
|
|
8
9
|
module CDDL
|
|
9
10
|
|
|
@@ -14,7 +15,7 @@ module CDDL
|
|
|
14
15
|
|
|
15
16
|
MANY = Float::INFINITY
|
|
16
17
|
|
|
17
|
-
MAX_RECURSE =
|
|
18
|
+
MAX_RECURSE = 128 # XXX
|
|
18
19
|
|
|
19
20
|
class ParseError < ArgumentError; end
|
|
20
21
|
|
|
@@ -139,7 +140,7 @@ module CDDL
|
|
|
139
140
|
arrayname = cname(arrayname ? arrayname.first : anno)
|
|
140
141
|
subtree[1..-1].each_with_index do |x, i|
|
|
141
142
|
if x[0] == :member
|
|
142
|
-
if Array === x[3] && x[3][0] == :
|
|
143
|
+
if Array === x[3] && x[3][0] == :text
|
|
143
144
|
memname = x[3][1] # preferably use key string
|
|
144
145
|
elsif memname = x[4].cbor_annotations
|
|
145
146
|
memname = memname.first # use value annotation otherwise
|
|
@@ -319,7 +320,8 @@ module CDDL
|
|
|
319
320
|
end
|
|
320
321
|
when :member
|
|
321
322
|
st = where[1]
|
|
322
|
-
|
|
323
|
+
fudge = 4 * (1 - (@recursion / MAX_RECURSE.to_f))**3 # get less generate-happy with more recursion
|
|
324
|
+
en = [where[2], [st, fudge].max].min # truncate to fudge unless must be more
|
|
323
325
|
st += rand(en + 1 - st) if en != st
|
|
324
326
|
kr = where[3]
|
|
325
327
|
vr = where[4]
|
|
@@ -348,7 +350,7 @@ module CDDL
|
|
|
348
350
|
fail BackTrack.new("Need #{where[1]}..#{where[2]} of these: #{[kr, vr].inspect}") unless where[1] == 0
|
|
349
351
|
[]
|
|
350
352
|
end
|
|
351
|
-
when :
|
|
353
|
+
when :text, :int, :float, :bytes
|
|
352
354
|
where[1]
|
|
353
355
|
when :range
|
|
354
356
|
rand(where[1])
|
|
@@ -390,15 +392,19 @@ module CDDL
|
|
|
390
392
|
case where[1]
|
|
391
393
|
when :size
|
|
392
394
|
should_be_int = generate1(control)
|
|
393
|
-
unless (target
|
|
395
|
+
unless (Array === target && target[0] == :prim && [0, 2, 3].include?(target[1])) && Integer === should_be_int && should_be_int >= 0
|
|
394
396
|
fail "Don't know yet how to generate #{where}"
|
|
395
397
|
end
|
|
396
398
|
s = Random.new.bytes(should_be_int)
|
|
397
|
-
|
|
399
|
+
case target[1]
|
|
400
|
+
when 0
|
|
398
401
|
# silently restrict to what we can put into a uint
|
|
399
402
|
s[0...8].bytes.inject(0) {|a, b| a << 8 | b }
|
|
400
|
-
|
|
403
|
+
when 2
|
|
401
404
|
s
|
|
405
|
+
when 3
|
|
406
|
+
Base64.urlsafe_encode64(s)[0...should_be_int]
|
|
407
|
+
# XXX generate word a la w = gen_word
|
|
402
408
|
end
|
|
403
409
|
when :bits
|
|
404
410
|
set_of_bits = Array.new(10) { generate1(control) } # XXX: ten?
|
|
@@ -517,7 +523,7 @@ module CDDL
|
|
|
517
523
|
end
|
|
518
524
|
end
|
|
519
525
|
|
|
520
|
-
VALUE_TYPE = {
|
|
526
|
+
VALUE_TYPE = {text: String, int: Integer, float: Float}
|
|
521
527
|
SIMPLE_VALUE = {
|
|
522
528
|
[:prim, 7, 20] => [true, false, :bool],
|
|
523
529
|
[:prim, 7, 21] => [true, true, :bool],
|
|
@@ -525,7 +531,7 @@ module CDDL
|
|
|
525
531
|
[:prim, 7, 23] => [true, :undefined, :undefined],
|
|
526
532
|
}
|
|
527
533
|
|
|
528
|
-
def extract_value(t)
|
|
534
|
+
def extract_value(t) # []
|
|
529
535
|
if vt = VALUE_TYPE[t[0]]
|
|
530
536
|
[true, t[1], vt]
|
|
531
537
|
elsif v = SIMPLE_VALUE[t]
|
|
@@ -642,7 +648,7 @@ module CDDL
|
|
|
642
648
|
d_check1 = d_check.dup
|
|
643
649
|
occ = 0
|
|
644
650
|
ann2 = []
|
|
645
|
-
while occ < e && (ann3 = map_check(d, d_check1, entries))
|
|
651
|
+
while occ < e && (ann3 = map_check(d, d_check1, entries)) && ann3 != []
|
|
646
652
|
occ += 1
|
|
647
653
|
ann2.concat(ann3)
|
|
648
654
|
end
|
|
@@ -660,7 +666,7 @@ module CDDL
|
|
|
660
666
|
# this is mostly quadratic; let's do the linear thing if possible
|
|
661
667
|
simple, simpleval = extract_value(k)
|
|
662
668
|
if simple
|
|
663
|
-
|
|
669
|
+
puts "SIMPLE: #{d_check.inspect} #{simpleval}" if ENV["CDDL_TRACE"]
|
|
664
670
|
# add occurrence check; check that val is present in the first place
|
|
665
671
|
actual = d.fetch(simpleval, :not_found)
|
|
666
672
|
if actual == :not_found
|
|
@@ -672,7 +678,7 @@ module CDDL
|
|
|
672
678
|
end
|
|
673
679
|
end
|
|
674
680
|
else
|
|
675
|
-
|
|
681
|
+
puts "COMPLEX: #{k.inspect} #{simple.inspect} #{simpleval.inspect}" if ENV["CDDL_TRACE"]
|
|
676
682
|
keys = d_check.keys
|
|
677
683
|
ta, keys = keys.partition{ |key| validate1(key, k)}
|
|
678
684
|
# XXX check ta.size against s/e
|
|
@@ -724,7 +730,7 @@ module CDDL
|
|
|
724
730
|
ann
|
|
725
731
|
else
|
|
726
732
|
if ENV["CDDL_TRACE"]
|
|
727
|
-
puts "MAP RESIDUAL: #{d_check.inspect}"
|
|
733
|
+
puts "MAP RESIDUAL: #{d_check.inspect} for #{where[1..-1]} and #{d.inspect}"
|
|
728
734
|
end
|
|
729
735
|
end
|
|
730
736
|
end
|
|
@@ -735,7 +741,7 @@ module CDDL
|
|
|
735
741
|
idx, ann = validate_forward(d, 0, where)
|
|
736
742
|
ann if validate_result(idx == d.size) { "#{validate_diag.inspect} -- cannot complete (#{idx}, #{d.size}) array #{d} for #{where}" }
|
|
737
743
|
end
|
|
738
|
-
when :
|
|
744
|
+
when :text, :int, :float, :bytes
|
|
739
745
|
_, v = extract_value(where)
|
|
740
746
|
[] if d == v
|
|
741
747
|
when :range
|
|
@@ -942,14 +948,34 @@ module CDDL
|
|
|
942
948
|
def value(n)
|
|
943
949
|
# cheat:
|
|
944
950
|
# warn n
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
951
|
+
s = n.to_s
|
|
952
|
+
if s[-1] == "'"
|
|
953
|
+
parts = s.split("'", 3)
|
|
954
|
+
if parts[2] != "" || parts[1] =~ /\\/
|
|
955
|
+
warn "*** Can't handle backslashes in #{s.inspect} yet"
|
|
956
|
+
end
|
|
957
|
+
[:bytes,
|
|
958
|
+
case parts[0]
|
|
959
|
+
when ""
|
|
960
|
+
parts[1].b
|
|
961
|
+
when "h"
|
|
962
|
+
parts[1].gsub(/\s/, "").chars.each_slice(2).map{ |x| Integer(x.join, 16).chr("BINARY") }.join
|
|
963
|
+
when "b64"
|
|
964
|
+
Base64.urlsafe_decode64(parts[1])
|
|
965
|
+
else
|
|
966
|
+
warn "*** Can't handle byte string type #{parts[0].inspect} yet"
|
|
967
|
+
end
|
|
968
|
+
]
|
|
969
|
+
else
|
|
970
|
+
val = eval(n.to_s)
|
|
971
|
+
# warn val
|
|
972
|
+
case val
|
|
973
|
+
when Integer; [:int, val]
|
|
974
|
+
when Numeric; [:float, val]
|
|
975
|
+
when String; [:text, val.force_encoding(Encoding::UTF_8)]
|
|
976
|
+
else fail "huh? value #{val.inspect}"
|
|
977
|
+
end
|
|
978
|
+
end
|
|
953
979
|
end
|
|
954
980
|
|
|
955
981
|
def workaround1(n)
|
|
@@ -988,7 +1014,7 @@ module CDDL
|
|
|
988
1014
|
fail [n, n.children, mk, mk.children].inspect
|
|
989
1015
|
end
|
|
990
1016
|
name = bw.to_s
|
|
991
|
-
[[:member, *occ, [:
|
|
1017
|
+
[[:member, *occ, [:text, name.force_encoding(Encoding::UTF_8)], type(nt)]]
|
|
992
1018
|
end
|
|
993
1019
|
else
|
|
994
1020
|
t = if nbw = nt.bareword
|
|
@@ -1000,8 +1026,8 @@ module CDDL
|
|
|
1000
1026
|
else
|
|
1001
1027
|
type(nt, true) # type can actually be a group here!
|
|
1002
1028
|
end
|
|
1003
|
-
|
|
1004
|
-
if t[0] == :grpent && (
|
|
1029
|
+
pp ["t is", t] if ENV["CDDL_TRACE"]
|
|
1030
|
+
if t[0] == :grpent && (occ == [1, 1])
|
|
1005
1031
|
# go through the members here and multiply the occs
|
|
1006
1032
|
t1 = t[1..-1].flatten(1)
|
|
1007
1033
|
if t1[0] == :recurse_grpent
|
data/test/test-cddl.rb
CHANGED
|
@@ -21,26 +21,26 @@ class TestABNF < Test::Unit::TestCase
|
|
|
21
21
|
|
|
22
22
|
EXPECTED_RULES = [:type1,
|
|
23
23
|
[:map,
|
|
24
|
-
[:member, 1, 1, [:
|
|
24
|
+
[:member, 1, 1, [:text, "application"], [:prim, 3]],
|
|
25
25
|
[:member,
|
|
26
26
|
1,
|
|
27
27
|
1,
|
|
28
|
-
[:
|
|
28
|
+
[:text, "reputons"],
|
|
29
29
|
[:array,
|
|
30
30
|
[:member,
|
|
31
31
|
0,
|
|
32
32
|
CDDL::MANY,
|
|
33
33
|
nil,
|
|
34
34
|
[:map,
|
|
35
|
-
[:member, 1, 1, [:
|
|
36
|
-
[:member, 1, 1, [:
|
|
37
|
-
[:member, 1, 1, [:
|
|
38
|
-
[:member, 1, 1, [:
|
|
39
|
-
[:member, 0, 1, [:
|
|
40
|
-
[:member, 0, 1, [:
|
|
41
|
-
[:member, 0, 1, [:
|
|
42
|
-
[:member, 0, 1, [:
|
|
43
|
-
[:member, 0, 1, [:
|
|
35
|
+
[:member, 1, 1, [:text, "rater"], [:prim, 3]],
|
|
36
|
+
[:member, 1, 1, [:text, "assertion"], [:prim, 3]],
|
|
37
|
+
[:member, 1, 1, [:text, "rated"], [:prim, 3]],
|
|
38
|
+
[:member, 1, 1, [:text, "rating"], [:prim, 7, 25]],
|
|
39
|
+
[:member, 0, 1, [:text, "confidence"], [:prim, 7, 25]],
|
|
40
|
+
[:member, 0, 1, [:text, "normal-rating"], [:prim, 7, 25]],
|
|
41
|
+
[:member, 0, 1, [:text, "sample-size"], [:prim, 0]],
|
|
42
|
+
[:member, 0, 1, [:text, "generated"], [:prim, 0]],
|
|
43
|
+
[:member, 0, 1, [:text, "expires"], [:prim, 0]],
|
|
44
44
|
[:member, 0, CDDL::MANY, [:prim, 3], [:prim]]]]]]]]
|
|
45
45
|
|
|
46
46
|
def test_aa_rfc7071_concise
|
|
@@ -59,9 +59,9 @@ class TestABNF < Test::Unit::TestCase
|
|
|
59
59
|
|
|
60
60
|
def test_generate_hex_bin
|
|
61
61
|
parser = CDDL::Parser.new <<HERE
|
|
62
|
-
test = [0x4711, 0b1011001110001111000]
|
|
62
|
+
test = [0x4711, 0xabcDEF, 0b1011001110001111000]
|
|
63
63
|
HERE
|
|
64
|
-
assert_equal [0x4711, 0b1011001110001111000], parser.generate
|
|
64
|
+
assert_equal [0x4711, 0xabcDEF, 0b1011001110001111000], parser.generate
|
|
65
65
|
end
|
|
66
66
|
|
|
67
67
|
def test_generate_le
|
|
@@ -182,6 +182,74 @@ HERE
|
|
|
182
182
|
refute parser.validate_for_test([2, 1], false)
|
|
183
183
|
end
|
|
184
184
|
|
|
185
|
+
def test_validate_a_map
|
|
186
|
+
parser = CDDL::Parser.new <<HERE
|
|
187
|
+
test = {* one: 1}
|
|
188
|
+
HERE
|
|
189
|
+
assert parser.validate_for_test({})
|
|
190
|
+
assert parser.validate_for_test({"one" => 1})
|
|
191
|
+
refute parser.validate_for_test({"one" => 2}, false)
|
|
192
|
+
refute parser.validate_for_test({"two" => 1}, false)
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def test_validate_a_group_map
|
|
196
|
+
parser = CDDL::Parser.new <<HERE
|
|
197
|
+
test = {* (text => 1)}
|
|
198
|
+
HERE
|
|
199
|
+
assert parser.validate_for_test({})
|
|
200
|
+
assert parser.validate_for_test({"one" => 1})
|
|
201
|
+
refute parser.validate_for_test({"one" => 2}, false)
|
|
202
|
+
assert parser.validate_for_test({"one" => 1, "two" => 1}, false)
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def test_validate_a_nontrivial_group_map
|
|
206
|
+
parser = CDDL::Parser.new <<HERE
|
|
207
|
+
test = {* (text => 1, text => 2)}
|
|
208
|
+
HERE
|
|
209
|
+
assert parser.validate_for_test({})
|
|
210
|
+
assert parser.validate_for_test({"one" => 2, "two" => 1})
|
|
211
|
+
assert parser.validate_for_test({"one" => 1, "two" => 2})
|
|
212
|
+
refute parser.validate_for_test({"one" => 1}, false)
|
|
213
|
+
assert parser.validate_for_test({"one" => 1, "two" => 2, "uno" => 1, "due" => 2})
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
def test_murray
|
|
218
|
+
parser = CDDL::Parser.new <<HERE
|
|
219
|
+
a = {
|
|
220
|
+
b
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
b = (
|
|
224
|
+
(x: int // y: int), z: int
|
|
225
|
+
)
|
|
226
|
+
HERE
|
|
227
|
+
assert parser.validate_for_test({})
|
|
228
|
+
assert parser.validate_for_test({"x" => 2, "z" => 1})
|
|
229
|
+
assert parser.validate_for_test({"y" => 1, "z" => 2})
|
|
230
|
+
refute parser.validate_for_test({"z" => 1}, false)
|
|
231
|
+
assert parser.validate_for_test({"one" => 1, "two" => 2, "uno" => 1, "due" => 2})
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
def test_murray_workaround
|
|
236
|
+
parser = CDDL::Parser.new <<HERE
|
|
237
|
+
a = {
|
|
238
|
+
b
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
b = ( z: int
|
|
242
|
+
(x: int // y: int)
|
|
243
|
+
)
|
|
244
|
+
HERE
|
|
245
|
+
assert parser.validate_for_test({})
|
|
246
|
+
assert parser.validate_for_test({"x" => 2, "z" => 1})
|
|
247
|
+
assert parser.validate_for_test({"y" => 1, "z" => 2})
|
|
248
|
+
refute parser.validate_for_test({"z" => 1}, false)
|
|
249
|
+
assert parser.validate_for_test({"one" => 1, "two" => 2, "uno" => 1, "due" => 2})
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
|
|
185
253
|
def test_validate_a_string
|
|
186
254
|
parser = CDDL::Parser.new <<HERE
|
|
187
255
|
test = [* one: "one"]
|
|
@@ -739,7 +807,7 @@ HERE
|
|
|
739
807
|
foo = {* bar}
|
|
740
808
|
bar = (* b: 1)
|
|
741
809
|
HERE
|
|
742
|
-
assert_equal [:type1, [:map, [:member, 0, CDDL::MANY, [:
|
|
810
|
+
assert_equal [:type1, [:map, [:member, 0, CDDL::MANY, [:text, "b"], [:int, 1]]]], parser.rules
|
|
743
811
|
end
|
|
744
812
|
|
|
745
813
|
def test_nested_group_many2
|
|
@@ -747,7 +815,7 @@ HERE
|
|
|
747
815
|
foo = {* bar}
|
|
748
816
|
bar = (b: 1)
|
|
749
817
|
HERE
|
|
750
|
-
assert_equal [:type1, [:map, [:member, 0, CDDL::MANY, [:
|
|
818
|
+
assert_equal [:type1, [:map, [:member, 0, CDDL::MANY, [:text, "b"], [:int, 1]]]], parser.rules
|
|
751
819
|
end
|
|
752
820
|
|
|
753
821
|
def test_nested_group_many3
|
|
@@ -755,7 +823,7 @@ HERE
|
|
|
755
823
|
foo = {* bar}
|
|
756
824
|
bar = (4*6 b: 1)
|
|
757
825
|
HERE
|
|
758
|
-
assert_equal [:type1, [:map, [:member, 0, CDDL::MANY, [:
|
|
826
|
+
assert_equal [:type1, [:map, [:member, 0, CDDL::MANY, [:text, "b"], [:int, 1]]]], parser.rules
|
|
759
827
|
end
|
|
760
828
|
|
|
761
829
|
def test_range_integer
|
|
@@ -1595,9 +1663,9 @@ identifier //= ( "ifmap" // "ifmap")
|
|
|
1595
1663
|
;identifier = ( "ifmap" // "ifmap" )
|
|
1596
1664
|
HERE
|
|
1597
1665
|
p parser.rules
|
|
1598
|
-
# - [:type1, [:array, [:member, 2, 2, nil, [:grpchoice, [[:member, 1, 1, nil, [:
|
|
1599
|
-
# - [:type1, [:array, [:member, 2, 2, nil, [:grpchoice, [[:grpchoice, [[:member, 1, 1, nil, [:
|
|
1600
|
-
# + [:type1, [:array, [:member, 2, 2, nil, [:grpent, [:grpchoice, [[:member, 1, 1, nil, [:
|
|
1666
|
+
# - [:type1, [:array, [:member, 2, 2, nil, [:grpchoice, [[:member, 1, 1, nil, [:text, "ifmap"]]]]]]]
|
|
1667
|
+
# - [:type1, [:array, [:member, 2, 2, nil, [:grpchoice, [[:grpchoice, [[:member, 1, 1, nil, [:text, "ifmap"]]], [[:member, 1, 1, nil, [:text, "ifmap"]]]]]]]]]
|
|
1668
|
+
# + [:type1, [:array, [:member, 2, 2, nil, [:grpent, [:grpchoice, [[:member, 1, 1, nil, [:text, "ifmap"]]], [[:member, 1, 1, nil, [:text, "ifmap"]]]]]]]]
|
|
1601
1669
|
g = parser.generate
|
|
1602
1670
|
assert_equal g, ["ifmap", "ifmap"]
|
|
1603
1671
|
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
reputation-object = {
|
|
2
|
+
application: tstr
|
|
3
|
+
reputons: [* reputon]
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
reputon = {
|
|
7
|
+
rater: tstr
|
|
8
|
+
assertion: tstr
|
|
9
|
+
rated: tstr
|
|
10
|
+
rating: float16
|
|
11
|
+
? confidence: float16
|
|
12
|
+
? normal-rating: float16
|
|
13
|
+
? sample-size: uint
|
|
14
|
+
? generated: uint
|
|
15
|
+
? expires: uint
|
|
16
|
+
* tstr => any
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
#
|
|
20
|
+
# a = b / c / d
|
|
21
|
+
# a = b / (c / d)
|
|
22
|
+
# b = "foo" ^ bar
|
|
23
|
+
# c = "bar" ^ baz
|
|
24
|
+
|
|
25
|
+
# foo: bar
|
|
26
|
+
# "foo" ^ => bar
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
# (rater: tstr // rater: uint)
|
|
30
|
+
# (rater: tstr / uint)
|
|
31
|
+
|
|
32
|
+
# (
|
|
33
|
+
# * tstr => uint
|
|
34
|
+
# rater: float16
|
|
35
|
+
# )
|
|
36
|
+
|
|
37
|
+
# a = b / c
|
|
38
|
+
# c = e / f
|
|
39
|
+
# a = b / (e / f)
|
|
40
|
+
|
|
41
|
+
# a = ( a // b )
|
|
42
|
+
# a = ( b // a )
|
|
43
|
+
|
|
44
|
+
# a = (uint .size 3) .le 100000
|
|
45
|
+
|
|
46
|
+
# name = uint .size 3
|
|
47
|
+
# reserved_name = name .le 100000
|
|
48
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
badaddr = text .regexp "[0-9A-Fa-f][0-9A-Fa-f]:[0-9A-Fa-f][0-9A-Fa-f]:[0-9A-Fa-f][0-9A-Fa-f]:[0-9A-Fa-f][0-9A-Fa-f]:[0-9A-Fa-f][0-9A-Fa-f]:[0-9A-Fa-f][0-9A-Fa-f]"
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
grasp-message = (message .within message-structure) / noop-message
|
|
2
|
+
|
|
3
|
+
message-structure = [MESSAGE_TYPE, session-id, ?initiator,
|
|
4
|
+
*grasp-option]
|
|
5
|
+
|
|
6
|
+
MESSAGE_TYPE = 0..255
|
|
7
|
+
session-id = 0..4294967295 ;up to 32 bits
|
|
8
|
+
grasp-option = any
|
|
9
|
+
|
|
10
|
+
message /= discovery-message
|
|
11
|
+
discovery-message = [M_DISCOVERY, session-id, initiator, objective]
|
|
12
|
+
|
|
13
|
+
message /= response-message ;response to Discovery
|
|
14
|
+
response-message = [M_RESPONSE, session-id, initiator, ttl,
|
|
15
|
+
(+locator-option // divert-option), ?objective]
|
|
16
|
+
|
|
17
|
+
message /= synch-message ;response to Synchronization request
|
|
18
|
+
synch-message = [M_SYNCH, session-id, objective]
|
|
19
|
+
|
|
20
|
+
message /= flood-message
|
|
21
|
+
flood-message = [M_FLOOD, session-id, initiator, ttl,
|
|
22
|
+
+[objective, (locator-option / [])]]
|
|
23
|
+
|
|
24
|
+
message /= request-negotiation-message
|
|
25
|
+
request-negotiation-message = [M_REQ_NEG, session-id, objective]
|
|
26
|
+
|
|
27
|
+
message /= request-synchronization-message
|
|
28
|
+
request-synchronization-message = [M_REQ_SYN, session-id, objective]
|
|
29
|
+
|
|
30
|
+
message /= negotiation-message
|
|
31
|
+
negotiation-message = [M_NEGOTIATE, session-id, objective]
|
|
32
|
+
|
|
33
|
+
message /= end-message
|
|
34
|
+
end-message = [M_END, session-id, accept-option / decline-option ]
|
|
35
|
+
|
|
36
|
+
message /= wait-message
|
|
37
|
+
wait-message = [M_WAIT, session-id, waiting-time]
|
|
38
|
+
|
|
39
|
+
message /= invalid-message
|
|
40
|
+
invalid-message = [M_INVALID, session-id, ?any]
|
|
41
|
+
|
|
42
|
+
noop-message = [M_NOOP]
|
|
43
|
+
|
|
44
|
+
divert-option = [O_DIVERT, +locator-option]
|
|
45
|
+
|
|
46
|
+
accept-option = [O_ACCEPT]
|
|
47
|
+
|
|
48
|
+
decline-option = [O_DECLINE, ?reason]
|
|
49
|
+
reason = text ;optional error message
|
|
50
|
+
|
|
51
|
+
waiting-time = 0..4294967295 ; in milliseconds
|
|
52
|
+
ttl = 0..4294967295 ; in milliseconds
|
|
53
|
+
|
|
54
|
+
locator-option /= [O_IPv4_LOCATOR, ipv4-address,
|
|
55
|
+
transport-proto, port-number]
|
|
56
|
+
ipv4-address = bytes .size 4
|
|
57
|
+
|
|
58
|
+
locator-option /= [O_IPv6_LOCATOR, ipv6-address,
|
|
59
|
+
transport-proto, port-number]
|
|
60
|
+
ipv6-address = bytes .size 16
|
|
61
|
+
|
|
62
|
+
locator-option /= [O_FQDN_LOCATOR, text, transport-proto, port-number]
|
|
63
|
+
|
|
64
|
+
transport-proto = IPPROTO_TCP / IPPROTO_UDP
|
|
65
|
+
IPPROTO_TCP = 6
|
|
66
|
+
IPPROTO_UDP = 17
|
|
67
|
+
port-number = 0..65535
|
|
68
|
+
|
|
69
|
+
locator-option /= [O_URI_LOCATOR, text]
|
|
70
|
+
|
|
71
|
+
initiator = ipv4-address / ipv6-address
|
|
72
|
+
|
|
73
|
+
objective-flags = uint .bits objective-flag
|
|
74
|
+
|
|
75
|
+
objective-flag = &(
|
|
76
|
+
F_DISC: 0 ; valid for discovery
|
|
77
|
+
F_NEG: 1 ; valid for negotiation
|
|
78
|
+
F_SYNCH: 2 ; valid for synchronization
|
|
79
|
+
F_NEG_DRY: 3 ; negotiation is dry-run
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
objective = [objective-name, objective-flags, loop-count, ?any]
|
|
83
|
+
|
|
84
|
+
objective-name = text ;see specification for uniqueness rules
|
|
85
|
+
|
|
86
|
+
loop-count = 0..255
|
|
87
|
+
|
|
88
|
+
; Constants for message types and option types
|
|
89
|
+
|
|
90
|
+
M_NOOP = 0
|
|
91
|
+
M_DISCOVERY = 1
|
|
92
|
+
M_RESPONSE = 2
|
|
93
|
+
M_REQ_NEG = 3
|
|
94
|
+
M_REQ_SYN = 4
|
|
95
|
+
M_NEGOTIATE = 5
|
|
96
|
+
M_END = 6
|
|
97
|
+
M_WAIT = 7
|
|
98
|
+
M_SYNCH = 8
|
|
99
|
+
M_FLOOD = 9
|
|
100
|
+
M_INVALID = 99
|
|
101
|
+
|
|
102
|
+
O_DIVERT = 100
|
|
103
|
+
O_ACCEPT = 101
|
|
104
|
+
O_DECLINE = 102
|
|
105
|
+
O_IPv6_LOCATOR = 103
|
|
106
|
+
O_IPv4_LOCATOR = 104
|
|
107
|
+
O_FQDN_LOCATOR = 105
|
|
108
|
+
O_URI_LOCATOR = 106
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
|
|
2
|
+
foo = { 1*relement }
|
|
3
|
+
|
|
4
|
+
context-element = 4711
|
|
5
|
+
|
|
6
|
+
relement = $$relement .within relement-generic
|
|
7
|
+
|
|
8
|
+
relement-generic = ( relement-codepoint => relement-value ) ; [1]
|
|
9
|
+
relement-codepoint = uint ; [1]
|
|
10
|
+
relement-value = any ; [1]
|
|
11
|
+
|
|
12
|
+
$$relement //= ( &(sender-loop-count:1) => 1..255 ) ; [2]
|
|
13
|
+
$$relement //= ( &(srv-element:2) => context-element ) ; [2]
|
|
14
|
+
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
foo = foo-specific .within foo-generic
|
|
2
|
+
foo-specific = { 1*$$relement }
|
|
3
|
+
foo-generic = { 1*relement-generic }
|
|
4
|
+
|
|
5
|
+
relement-generic = ( relement-codepoint => relement-value ) ; [1]
|
|
6
|
+
relement-codepoint = uint ; [1]
|
|
7
|
+
relement-value = any ; [1]
|
|
8
|
+
|
|
9
|
+
$$relement //= ( &(sender-loop-count:1) => 1..255 ) ; [2]
|
|
10
|
+
$$relement //= ( &(srv-element:2) => context-element ) ; [2]
|
|
11
|
+
context-element = "and so on"
|
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.8.
|
|
4
|
+
version: 0.8.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:
|
|
11
|
+
date: 2018-12-07 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: cbor-diag
|
|
@@ -94,19 +94,24 @@ files:
|
|
|
94
94
|
- lib/cbor-pp-play.rb
|
|
95
95
|
- lib/cbor-pp.rb
|
|
96
96
|
- lib/cddl.rb
|
|
97
|
+
- test-data/7071-concise-cut.cddl
|
|
97
98
|
- test-data/7071-concise.cddl
|
|
98
99
|
- test-data/7071-verbose.cddl
|
|
99
100
|
- test-data/a.cddl
|
|
101
|
+
- test-data/ambig.cddl
|
|
100
102
|
- test-data/b.cddl
|
|
103
|
+
- test-data/badaddr.cddl
|
|
101
104
|
- test-data/basic_syntax_example.cddl
|
|
102
105
|
- test-data/cdni-ct.cddl
|
|
103
106
|
- test-data/cose.cddl
|
|
104
107
|
- test-data/dcaf.cddl
|
|
105
108
|
- test-data/dcaf1.cddl
|
|
109
|
+
- test-data/dotsize.cddl
|
|
106
110
|
- test-data/extractor-demo.cddl
|
|
107
111
|
- test-data/grasp-01-extract.cddl
|
|
108
112
|
- test-data/grasp-01-test.cddl
|
|
109
113
|
- test-data/grasp-01.cddl
|
|
114
|
+
- test-data/grasp-09.cddl
|
|
110
115
|
- test-data/grasp-v1.cddl
|
|
111
116
|
- test-data/grasp-v2X.cddl
|
|
112
117
|
- test-data/ifmap-base-2.0v17.cddl
|
|
@@ -114,10 +119,15 @@ files:
|
|
|
114
119
|
- test-data/ifmap-metadata-2.2v9_fh-cabo.cddl
|
|
115
120
|
- test-data/ifmap2.cddl
|
|
116
121
|
- test-data/jcr-ex.cddl
|
|
122
|
+
- test-data/kevin5.cddl
|
|
123
|
+
- test-data/map-group.cddl
|
|
124
|
+
- test-data/mapkey.cddl
|
|
117
125
|
- test-data/minimal.cddl
|
|
118
126
|
- test-data/patch1.cddl
|
|
119
127
|
- test-data/reused_named_group.cddl
|
|
120
128
|
- test-data/structure.cddl
|
|
129
|
+
- test-data/toerless0.cddl
|
|
130
|
+
- test-data/toerless1.cddl
|
|
121
131
|
- test-data/two_anonymous_groups.cddl
|
|
122
132
|
- test-data/wrong1.cddl
|
|
123
133
|
- test-data/wrong1a.cddl
|
|
@@ -145,7 +155,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
145
155
|
version: '0'
|
|
146
156
|
requirements: []
|
|
147
157
|
rubyforge_project:
|
|
148
|
-
rubygems_version: 2.
|
|
158
|
+
rubygems_version: 2.7.6
|
|
149
159
|
signing_key:
|
|
150
160
|
specification_version: 4
|
|
151
161
|
summary: CDDL generator and validator.
|