cddl 0.4.1 → 0.4.2

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: d81421c45b8589d98a0bee597ebf58684b6dc47d
4
- data.tar.gz: 2c43ce26e9ec1061a91ffc078eb797293e6e861c
3
+ metadata.gz: 0f6311c506c4a4e5cbf7e7ae7311301a9d4b6c8d
4
+ data.tar.gz: e6fdfe83c6aec225ce434ae492a709fd06d0c890
5
5
  SHA512:
6
- metadata.gz: a59f236c132f7d3c4c20b20275270a304873abe3a0a527cd923a84d683ab953d59a65fa006f7de0c81de45c0d175bb86dcbb7abc680aa5f83e7753464d0dc8d6
7
- data.tar.gz: 2724e39b65ff8d6b2de65845ae67a713276fd99743625f2745bc4d6a6c0433ae43f736d47e1741f5e4df936c5102f112e675e541cffa3991a98abb54e93c9b67
6
+ metadata.gz: c2926569f00e5e7e509b3e6d05271da2c0d79a79eb46e38e97701218fe339113d08a8057369ff3c4b5f02bdd3f5fbb80ebc34875c6767b619ea327f722bf7ce3
7
+ data.tar.gz: 3df458899c4ed7890ef68a40b3c64484599b2805084eb9c8eee15789c94c269452c6352ce34d77dd078e612957c29ded13b650520c179dc6fe886f853e2a60e6
@@ -1,6 +1,6 @@
1
1
  spec = Gem::Specification.new do |s|
2
2
  s.name = 'cddl'
3
- s.version = '0.4.1'
3
+ s.version = '0.4.2'
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')
@@ -30,7 +30,7 @@ annotator = "." id
30
30
  group = "(" S *grpent S ")"
31
31
  / *grpent
32
32
 
33
- grpent = [occur S] [memberkey S] type1 optcom
33
+ grpent = [occur S] [memberkey S] type optcom
34
34
  / [occur S] groupname [genericarg] optcom ; always preempted by previous...
35
35
 
36
36
  memberkey = type1 S "=>"
@@ -115,6 +115,14 @@ module CDDL
115
115
  result
116
116
  end
117
117
 
118
+ def lookup_recurse_grpent(name)
119
+ rule = @stage1[name]
120
+ [rule[0], *rule[1..-1].map {|x|
121
+ fail rule.inspect if x.size != 1
122
+ x[0]
123
+ }]
124
+ end
125
+
118
126
  # Memoize a bit here
119
127
 
120
128
  REGEXP_FOR_STRING = Hash.new {|h, k|
@@ -132,6 +140,18 @@ module CDDL
132
140
  generate1(where[rand(where.size-1)+1])
133
141
  when :map
134
142
  Hash[where[1..-1].flat_map {|m| generate1(m, true)}]
143
+ when :recurse_grpent
144
+ rule = lookup_recurse_grpent(where[1])
145
+ if @recursion < MAX_RECURSE
146
+ @recursion += 1
147
+ #p ["recurse_grpent", *rule]
148
+ #r = generate1(rule)
149
+ r = rule[1..-1].flat_map {|m| generate1(m, inmap)}
150
+ @recursion -= 1
151
+ r
152
+ else
153
+ fail "Deep recursion into #{name}: #{@stage1[name]}, not yet implemented"
154
+ end
135
155
  when :array, :grpent
136
156
  r = where[1..-1].flat_map {|m| generate1(m).map{|e| e[1]}}
137
157
  .flat_map {|e| Array === e && e[0] == :grpent ? e[1..-1] : [e]}
@@ -233,6 +253,7 @@ module CDDL
233
253
  rule = @stage1[name]
234
254
  if @recursion < MAX_RECURSE
235
255
  @recursion += 1
256
+ #p ["recurse", *rule]
236
257
  r = generate1(rule)
237
258
  @recursion -= 1
238
259
  r
@@ -240,7 +261,7 @@ module CDDL
240
261
  fail "Deep recursion into #{name}: #{@stage1[name]}, not yet implemented"
241
262
  end
242
263
  else
243
- fail "Don't know how to generate from #{where[0]}"
264
+ fail "Don't know how to generate from #{where[0]} in #{where.inspect}"
244
265
  end
245
266
  end
246
267
 
@@ -289,15 +310,22 @@ module CDDL
289
310
  i = 0
290
311
  where[1..-1].each { |r|
291
312
  t, s, e, _k, v = r # XXX
292
- fail unless t == :member
293
- occ = 0
294
- while ((occ < e) && i != d.size && (n = validate_linear(d, start+i, v)))
313
+ if t == :recurse_grpent
314
+ rule = lookup_recurse_grpent(s)
315
+ n = validate_linear(d, start+i, rule)
316
+ return false unless n
295
317
  i += n
296
- occ += 1
297
- end
298
- if occ < s
299
- @last_message = "occur not reached in array #{d} for #{where}"
300
- return false
318
+ else
319
+ fail r.inspect unless t == :member
320
+ occ = 0
321
+ while ((occ < e) && i != d.size && (n = validate_linear(d, start+i, v)))
322
+ i += n
323
+ occ += 1
324
+ end
325
+ if occ < s
326
+ @last_message = "occur not reached in array #{d} for #{where}"
327
+ return false
328
+ end
301
329
  end
302
330
  }
303
331
  i
@@ -483,13 +511,26 @@ module CDDL
483
511
  end
484
512
  end
485
513
 
514
+ RECURSE_TYPE = {grpent: :recurse_grpent, type1: :recurse}
515
+ RECURSE_TYPE.default_proc = proc do |a|
516
+ fail a.inspect
517
+ end
518
+
486
519
  def r_process(n, r, bindings = {})
487
520
  t = r[0]
488
521
  # puts "Processing rule #{n} = #{t}"
489
522
  @stage1[n] ||= begin
490
- @stage1[n] = [:type1, [:recurse, n]]
523
+ @stage1[n] = [t, [RECURSE_TYPE[t], n]]
491
524
  @bindings.push(bindings)
492
- r = [t, *r[1..-1].map {|e| send(t, e)}]
525
+ r = [t, *r[1..-1].map {|e|
526
+ case t
527
+ when :grpent
528
+ grpent(e)
529
+ when :type1
530
+ type1(e, r.size == 2) # a single type1 could be a group
531
+ else
532
+ fail t
533
+ end}]
493
534
  @bindings.pop
494
535
  r
495
536
  end
@@ -509,11 +550,16 @@ module CDDL
509
550
  end
510
551
 
511
552
  def grpent(n) # returns array of entries
553
+ nt = n.type || n.bareword.s.type # check for grpchoice later
554
+ unless nt
555
+ warn @abnf.ast?
556
+ fail ["ntype", n, n.children].inspect
557
+ end
512
558
  occ = occur(n.occur)
513
559
  if mk = n.memberkey # work around unclear bug in ast generation below
514
- fail n.inspect unless n.type1
515
- if (t1 = mk.type1) || ((t1 = mk.s) && (t1 = t1.type) && (t1 = t1.type1)) # workaround
516
- [[:member, *occ, type1(t1), type1(n.type1)]]
560
+ if (t1 = mk.type1 || t1 = mk.value ||
561
+ ((t1 = mk.s) && (t1 = t1.type) && (t1 = t1.type1))) # workaround
562
+ [[:member, *occ, type1(t1), type(nt)]]
517
563
  else
518
564
  bw = mk.bareword
519
565
  unless bw
@@ -521,31 +567,36 @@ module CDDL
521
567
  fail [n, n.children, mk, mk.children].inspect
522
568
  end
523
569
  name = bw.to_s
524
- [[:member, *occ, [:string, name], type1(n.type1)]]
570
+ [[:member, *occ, [:string, name], type(nt)]]
525
571
  end
526
572
  else
527
- t = if n.bareword # work around unclear bug, part 2
528
- t1 = n.bareword.type1 || n.bareword.s.type.type1 # workaround
573
+ t = if nbw = nt.bareword
574
+ t1 = nbw.type1 # || n.bareword.s.type.type1 # workaround
529
575
  type1(t1, true)
530
576
  else
531
- type1(n.type1, true) # type1 can be a group here!
577
+ type(nt, true) # type can actually be a group here!
532
578
  end
579
+ # pp ["t is", t]
533
580
  if t[0] == :grpent && (@insides.last != :array || occ == [1, 1])
534
581
  # go through the members here and multiply the occs
535
582
  t1 = t[1..-1].flatten(1)
536
- t1.flat_map {|t2|
537
- if t2[0] == :member
538
- [t2]
539
- else
540
- fail unless t2[0] == :grpent # XXX Where is the nested multiplication here?
541
- t2[1..-1]
542
- end
543
- }.map {|mem|
544
- mem[1] *= occ[0]
545
- mem[2] *= occ[1] # Does all the infinity magic
546
- # p mem
547
- mem
548
- }
583
+ if t1[0] == :recurse_grpent
584
+ [t1]
585
+ else
586
+ t1.flat_map {|t2|
587
+ if t2[0] == :member
588
+ [t2]
589
+ else
590
+ fail t1.inspect unless t2[0] == :grpent # XXX Where is the nested multiplication here?
591
+ t2[1..-1]
592
+ end
593
+ }.map {|mem|
594
+ mem[1] *= occ[0]
595
+ mem[2] *= occ[1] # Does all the infinity magic
596
+ # p mem
597
+ mem
598
+ }
599
+ end
549
600
  else
550
601
  if t[0] == :grpent
551
602
  t = [t[0], *t[1..-1].flatten(1)]
@@ -688,8 +739,9 @@ module CDDL
688
739
  end
689
740
  end
690
741
 
691
- def type(n)
692
- s = n.children(:type1).map {|ch| type1(ch)}
742
+ def type(n, canbegroup = false)
743
+ # pp ["nch", n.children]
744
+ s = n.children(:type1).map {|ch| type1(ch, canbegroup)}
693
745
  if s.size == 1
694
746
  s.first
695
747
  else
@@ -0,0 +1,72 @@
1
+ ; draft-ietf-cdni-control-triggers-06.txt
2
+
3
+ CIT-object = CIT-command / Trigger-Status-Resource / Trigger-Collection
4
+
5
+ CIT-command ; use media type application/cdni.ci.TriggerCommand+json
6
+ = {
7
+ ? trigger: Triggerspec
8
+ ? cancel: [* URI]
9
+ cdn-path: [* Cdn-PID]
10
+ }
11
+
12
+ Trigger-Status-Resource ; application/cdni.ci.TriggerStatus+json.
13
+ = {
14
+ trigger: Triggerspec
15
+ ctime: Absolute-Time
16
+ mtime: Absolute-Time
17
+ ? etime: Absolute-Time
18
+ status: Trigger-Status
19
+ ? errors: [* Error-Description]
20
+ }
21
+
22
+ Trigger-Collection ; application/cdni.ci.TriggerCollection+json
23
+ = {
24
+ triggers: [* URI]
25
+ ? staleresourcetime: int ; time in seconds
26
+ ? coll-all: URI
27
+ ? coll-pending: URI
28
+ ? coll-active: URI
29
+ ? coll-complete: URI
30
+ ? coll-failed: URI
31
+ ? cdn-id: Cdn-PID
32
+ }
33
+
34
+ Triggerspec = { ; 5.2.1
35
+ type: Trigger-Type
36
+ ? metadata.urls: [* URI]
37
+ ? content.urls: [* URI]
38
+ ? content.ccid: [* Ccid]
39
+ ? metadata.patterns: [* Pattern-Match]
40
+ ? content.patterns: [* Pattern-Match]
41
+ }
42
+
43
+ Trigger-Type = "preposition" / "invalidate" / "purge" ; 5.2.2
44
+
45
+ Trigger-Status = "pending" / "active" / "complete" / "processed"
46
+ / "failed" / "cancelling" / "cancelled" ; 5.2.3
47
+
48
+ Pattern-Match = { ; 5.2.4
49
+ pattern: tstr
50
+ ? case-sensitive: bool
51
+ ? match-query-string: bool
52
+ }
53
+
54
+ Absolute-Time = number ; seconds since UNIX epoch, 5.2.5
55
+
56
+ Error-Description = { ; 5.2.6
57
+ error: Error-Code
58
+ ? metadata.urls: [* URI]
59
+ ? content.urls: [* URI]
60
+ ? metadata.patterns: [* Pattern-Match]
61
+ ? content.patterns: [* Pattern-Match]
62
+ ? description: tstr
63
+ }
64
+
65
+ Error-Code = "emeta" / "econtent" / "eperm" / "ereject"
66
+ / "ecdn" / "ecancelled" ; 5.2.7
67
+
68
+ Ccid = tstr ; see I-D.ietf-cdni-metadata
69
+
70
+ Cdn-PID = tstr .regexp "AS[0-9]+:[0-9]+"
71
+
72
+ URI = tstr
@@ -374,6 +374,82 @@ HERE
374
374
  end
375
375
 
376
376
 
377
+ def test_simple_alternative
378
+ parser = CDDL::Parser.new <<HERE
379
+ test = {
380
+ foo: 1
381
+ bar: 1 / 2
382
+ baz: 3
383
+ bee: 4
384
+ }
385
+ HERE
386
+ # pp parser.rules
387
+ expected1 = {'foo' => 1, 'bar' => 1, 'baz' => 3, 'bee' => 4}
388
+ expected2 = {'foo' => 1, 'bar' => 2, 'baz' => 3, 'bee' => 4}
389
+ 10.times {
390
+ g = parser.generate
391
+ # pp g
392
+ assert expected1 == g || expected2 == g
393
+ assert parser.validate(g)
394
+ }
395
+ end
396
+
397
+ def test_another_simple_alternative
398
+ parser = CDDL::Parser.new <<HERE
399
+ test = {
400
+ bar: int / true
401
+ }
402
+ HERE
403
+ # pp parser.rules
404
+ 10.times {
405
+ g = parser.generate
406
+ # pp ["tasa", g]
407
+ bar = g['bar']
408
+ assert bar == true || Integer(bar)
409
+ assert parser.validate(g)
410
+ }
411
+ end
412
+
413
+ def test_simple_alternative_in_array
414
+ parser = CDDL::Parser.new <<HERE
415
+ test = [
416
+ 1 / 2
417
+ 3 / 4
418
+ ]
419
+ HERE
420
+ # pp parser.rules
421
+ 10.times {
422
+ g = parser.generate
423
+ #pp ["saia", g]
424
+ assert_equal g.size, 2
425
+ assert [1, 2].include? g[0]
426
+ assert [3, 4].include? g[1]
427
+ assert parser.validate(g)
428
+ }
429
+ end
430
+
431
+ def test_simple_alternative_in_array2
432
+ parser = CDDL::Parser.new <<HERE
433
+ test = [
434
+ 1 / 2
435
+ bar
436
+ foob: 3 / 4
437
+ ]
438
+ bar = 5 / 6
439
+ HERE
440
+ # pp parser.rules
441
+ 10.times {
442
+ g = parser.generate
443
+ # pp ["saia", g]
444
+ assert_equal g.size, 3
445
+ assert [1, 2].include? g[0]
446
+ assert [5, 6].include? g[1]
447
+ assert [3, 4].include? g[2]
448
+ assert parser.validate(g)
449
+ }
450
+ end
451
+
452
+
377
453
  def test_validate_number_key
378
454
  parser = CDDL::Parser.new <<HERE
379
455
  test = [test1, test2, test3]
@@ -825,9 +901,83 @@ a = [a] / 1
825
901
  HERE
826
902
  10.times {
827
903
  g = parser.generate
828
- pp ["recurse-test", g]
904
+ pp ["recurse-test1", g]
905
+ assert parser.validate(g)
906
+ }
907
+ end
908
+
909
+ def test_endless_group_recursion
910
+ parser = CDDL::Parser.new <<HERE
911
+ b = {a}
912
+ a = (
913
+ foo: int
914
+ a
915
+ )
916
+ HERE
917
+ assert_raise { parser.validate(1) }
918
+ assert_raise { parser.generate }
919
+ end
920
+
921
+ def test_non_group_recursion
922
+ parser = CDDL::Parser.new <<HERE
923
+ a = {
924
+ foo: int
925
+ bar: ([a] / 1)
926
+ }
927
+ HERE
928
+ 10.times {
929
+ g = parser.generate
930
+ # pp ["non-recurse-test", g]
931
+ assert parser.validate(g)
932
+ }
933
+ end
934
+
935
+ def test_group_recursion
936
+ parser = CDDL::Parser.new <<HERE
937
+ b = {a}
938
+ a = (
939
+ foo: int
940
+ bar: ([a] / 1)
941
+ )
942
+ HERE
943
+ p parser.rules
944
+ 10.times {
945
+ g = parser.generate
946
+ # pp ["recurse-group-test", g]
829
947
  assert parser.validate(g)
830
948
  }
831
949
  end
832
950
 
951
+ def test_group_recursion_fail1
952
+ parser = CDDL::Parser.new <<HERE
953
+ b = {a}
954
+ a = (
955
+ foo: int
956
+ bar: ([a: a] / 1)
957
+ )
958
+ HERE
959
+ assert_raise { p parser.rules }
960
+ end
961
+
962
+ def test_empty_group
963
+ parser = CDDL::Parser.new <<HERE
964
+ a = {b}
965
+ b = ()
966
+ HERE
967
+ assert_equal({}, parser.generate)
968
+ assert parser.validate({})
969
+ end
970
+
971
+
972
+ def test_empty_group_indirect
973
+ parser = CDDL::Parser.new <<HERE
974
+ a = {b}
975
+ b = (c)
976
+ c = ()
977
+ HERE
978
+ # XXX
979
+ # assert_equal({}, parser.generate)
980
+ # assert parser.validate({})
981
+ end
982
+
833
983
  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.4.1
4
+ version: 0.4.2
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-24 00:00:00.000000000 Z
11
+ date: 2015-04-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cbor-diag
@@ -101,6 +101,7 @@ files:
101
101
  - test-data/7071-concise.cddl
102
102
  - test-data/7071-verbose.cddl
103
103
  - test-data/basic_syntax_example.cddl
104
+ - test-data/cdni-ct.cddl
104
105
  - test-data/dcaf1.cddl
105
106
  - test-data/jcr-ex.cddl
106
107
  - test-data/minimal.cddl