cddl 0.1.7 → 0.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 18e49f92e707d92bff7762be5f4905702b48f179
4
- data.tar.gz: 4f3fb0f3fc4573ec189ab16cf280ae1fcb63ead0
3
+ metadata.gz: 069ab5627679f8b9c644f6469eff2a3760c4c911
4
+ data.tar.gz: 39c18606d5c35934d4933ff96c444a7f685f7003
5
5
  SHA512:
6
- metadata.gz: 81b2b4241507fdb26f88164daacff36dc73e7f67df3d85662a9f76999f1aa7d7ae2fce72e93e87fbe55991a7b3f8459aa064cfff47f545f05e1904a3e1bef20a
7
- data.tar.gz: 89b707e68854724d991785432dac1ed3e2814ae0d92791e3b30ade4e769eeb8508cfb457e0f4fc19b36494320ddbc98caa1ad04b7551359e15c59d4aae7a7a0f
6
+ metadata.gz: 65ff54e705aa476af42d7157cfa87120678b59d6c8177d86a6552abd5c4ee135531b8c17dcb078c34fed3a773c67aaddc6e30c645e9c40af22bb1fca6c6d1a08
7
+ data.tar.gz: 32049a27a9a6a2ca7080a7d9bffde7fa7c3e2f0e88eaac030fb9ea97b87e0bd0b5844d660ec730ca321665f96d01eb68af78f119c809974178bde444bb7b8638
data/cddl.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  spec = Gem::Specification.new do |s|
2
2
  s.name = 'cddl'
3
- s.version = '0.1.7'
3
+ s.version = '0.1.8'
4
4
  s.summary = "CDDL generator and validator."
5
5
  s.description = %{A parser, generator, and validator for CDDL}
6
6
  s.add_dependency('cbor-diag')
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 = ALPHA *(ALPHA / DIGIT / "_" / "-")
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
- fail "Duplicate rule #{n}" if @rules[n]
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(*n.children(:type2).map {|l|
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
- pp parser.generate
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
- pp parser.generate
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.7
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-05 00:00:00.000000000 Z
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