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 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