cddlc 0.1.2 → 0.1.4

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
  SHA256:
3
- metadata.gz: ed5e9bd6c8caace67d29c6549fd30d59fc2c17c06b671f63868d2ecb6ea0031b
4
- data.tar.gz: 03d6d40e1ebf19da17117ca725ba09c60c33867606953d2566fd86ace2805e9a
3
+ metadata.gz: 000da759c9346bf077d53d94e0d303e6a60e2384ca81fe8a2e746a0f3a058ebc
4
+ data.tar.gz: 93a2e95d3ab753726aa62f97e036e554bf2ca4c008eb7189dca1c87e63b53dd3
5
5
  SHA512:
6
- metadata.gz: 2b1790d8845935f61f7c12070dbb95f223a6e1914c813dbf85e4ae3979b1fbcbf37abd5730a3a471c1a5777464a8fc966d36835e20df41d3e19a17203e0969f8
7
- data.tar.gz: f0884c20358c0a7edaf9df050c79d93f3df7dfb42ceb44ee59b3cc0cb8f318a5ad5efa08964dd259d3a211dd6bcc8a1b2eed5f636cae4ca5a80b524c3a40fdab
6
+ metadata.gz: 2e501521ac303e9a8aba48198037a3f941f2ff3b6e4c875ea42bc64e8052c4a78516c0d7cb2c5a1a7efc1827295f5c446e349c51782ac6f52e9c009d341a8bd0
7
+ data.tar.gz: f9ae3b76b1bbd807816b959e02d8ddaf7d79be417dfe3c3d56eb0fca3496eafd2d50f2b4496a8bd8abffb3fb539e3fb3702c140679cd25329d0a9cfe4c9af55d
data/bin/cddlc CHANGED
@@ -64,6 +64,17 @@ begin
64
64
  opts.on("-tFMT", "--to=FMT", [:basic, :neat, :json, :yaml, :enum, :cddl], "Target format") do |v|
65
65
  $options.target = v
66
66
  end
67
+ opts.on("-sRULE", "--start=RULE", String, "Start rule name") do |v|
68
+ $options.start = v
69
+ end
70
+ opts.on("-iIMPORT", "--import=IMPORT", String, "Import [namespace=]reference") do |v|
71
+ $options.import ||= []
72
+ $options.import << v
73
+ end
74
+ opts.on("-IINCLUDE", "--include=INCLUDE", String, "Include [namespace=]reference") do |v|
75
+ $options.include ||= []
76
+ $options.include << v
77
+ end
67
78
  end
68
79
  op.parse!
69
80
  rescue Exception => e
@@ -71,11 +82,40 @@ rescue Exception => e
71
82
  exit 1
72
83
  end
73
84
 
85
+ cddl_file = ""
86
+ if $options.start
87
+ cddl_file << "$.start.$ = #{$options.start}\n"
88
+ end
89
+
90
+ [[$options.include, "include"], [$options.import, "import"]].each do |arr, directive|
91
+ if arr
92
+ arr.each do |ref|
93
+ asname, refname = ref.split("=", 2)
94
+ unless refname
95
+ refname = asname
96
+ asname = nil
97
+ end
98
+ cddl_file << ";# #{directive} #{refname}"
99
+ cddl_file << " as #{asname}" if asname
100
+ cddl_file << "\n"
101
+ end
102
+ end
103
+ end
104
+
105
+ if $options.verbose
106
+ warn "::: generated from options:"
107
+ warn cddl_file
108
+ warn ":::\n\n"
109
+ end
110
+
74
111
  if ARGV == []
75
- puts op
76
- exit 1
112
+ if cddl_file == ""
113
+ puts op
114
+ exit 1
115
+ end
116
+ else
117
+ cddl_file << ARGF.read
77
118
  end
78
- cddl_file = ARGF.read
79
119
 
80
120
  cddl = CDDL.from_cddl(cddl_file)
81
121
  result = if $options.rules
data/cddlc.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "cddlc"
3
- s.version = "0.1.2"
3
+ s.version = "0.1.4"
4
4
  s.summary = "CDDL (Concise Data Definition Language) converters and miscellaneous tools"
5
5
  s.description = %q{cddlc implements converters and miscellaneous tools for CDDL, RFC 8610}
6
6
  s.author = "Carsten Bormann"
@@ -0,0 +1,213 @@
1
+
2
+ grasp-message = (message .within message-structure) / noop-message
3
+
4
+ message-structure = [MESSAGE_TYPE, session-id, ?initiator,
5
+ *grasp-option]
6
+
7
+ MESSAGE_TYPE = 0..255
8
+ session-id = 0..4294967295 ; up to 32 bits
9
+ grasp-option = any
10
+
11
+
12
+ discovery-message = [M_DISCOVERY, session-id, initiator, objective]
13
+
14
+
15
+ response-message = [M_RESPONSE, session-id, initiator, ttl,
16
+ (+locator-option // divert-option), ?objective]
17
+
18
+ ttl = 0..4294967295 ; in milliseconds
19
+
20
+
21
+ request-negotiation-message = [M_REQ_NEG, session-id, objective]
22
+
23
+ request-synchronization-message = [M_REQ_SYN, session-id, objective]
24
+
25
+
26
+ negotiation-message = [M_NEGOTIATE, session-id, objective]
27
+
28
+
29
+ end-message = [M_END, session-id, accept-option / decline-option]
30
+
31
+
32
+ wait-message = [M_WAIT, session-id, waiting-time]
33
+ waiting-time = 0..4294967295 ; in milliseconds
34
+
35
+
36
+ synch-message = [M_SYNCH, session-id, objective]
37
+
38
+
39
+ flood-message = [M_FLOOD, session-id, initiator, ttl,
40
+ +[objective, (locator-option / [])]]
41
+
42
+ ttl = 0..4294967295 ; in milliseconds
43
+
44
+
45
+ invalid-message = [M_INVALID, session-id, ?any]
46
+
47
+
48
+ noop-message = [M_NOOP]
49
+
50
+
51
+ divert-option = [O_DIVERT, +locator-option]
52
+
53
+
54
+ accept-option = [O_ACCEPT]
55
+
56
+
57
+ decline-option = [O_DECLINE, ?reason]
58
+ reason = text ; optional UTF-8 error message
59
+
60
+
61
+ ipv6-locator-option = [O_IPv6_LOCATOR, ipv6-address,
62
+ transport-proto, port-number]
63
+ ipv6-address = bytes .size 16
64
+
65
+ transport-proto = IPPROTO_TCP / IPPROTO_UDP
66
+ IPPROTO_TCP = 6
67
+ IPPROTO_UDP = 17
68
+ port-number = 0..65535
69
+
70
+
71
+ ipv4-locator-option = [O_IPv4_LOCATOR, ipv4-address,
72
+ transport-proto, port-number]
73
+ ipv4-address = bytes .size 4
74
+
75
+
76
+ fqdn-locator-option = [O_FQDN_LOCATOR, text,
77
+ transport-proto, port-number]
78
+
79
+
80
+ uri-locator-option = [O_URI_LOCATOR, text,
81
+ transport-proto / null, port-number / null]
82
+
83
+
84
+ objective = [objective-name, objective-flags,
85
+ loop-count, ?objective-value]
86
+
87
+ objective-name = text
88
+ objective-value = any
89
+ loop-count = 0..255
90
+
91
+
92
+ objective-flags = uint .bits objective-flag
93
+ objective-flag = &(
94
+ F_DISC: 0 ; valid for discovery
95
+ F_NEG: 1 ; valid for negotiation
96
+ F_SYNCH: 2 ; valid for synchronization
97
+ F_NEG_DRY: 3 ; negotiation is a dry run
98
+ )
99
+
100
+
101
+ grasp-message = (message .within message-structure) / noop-message
102
+
103
+ message-structure = [MESSAGE_TYPE, session-id, ?initiator,
104
+ *grasp-option]
105
+
106
+ MESSAGE_TYPE = 0..255
107
+ session-id = 0..4294967295 ; up to 32 bits
108
+ grasp-option = any
109
+
110
+ message /= discovery-message
111
+ discovery-message = [M_DISCOVERY, session-id, initiator, objective]
112
+
113
+ message /= response-message ; response to Discovery
114
+ response-message = [M_RESPONSE, session-id, initiator, ttl,
115
+ (+locator-option // divert-option), ?objective]
116
+
117
+ message /= synch-message ; response to Synchronization request
118
+ synch-message = [M_SYNCH, session-id, objective]
119
+
120
+ message /= flood-message
121
+ flood-message = [M_FLOOD, session-id, initiator, ttl,
122
+ +[objective, (locator-option / [])]]
123
+
124
+ message /= request-negotiation-message
125
+ request-negotiation-message = [M_REQ_NEG, session-id, objective]
126
+
127
+ message /= request-synchronization-message
128
+ request-synchronization-message = [M_REQ_SYN, session-id, objective]
129
+
130
+ message /= negotiation-message
131
+ negotiation-message = [M_NEGOTIATE, session-id, objective]
132
+
133
+ message /= end-message
134
+ end-message = [M_END, session-id, accept-option / decline-option]
135
+
136
+ message /= wait-message
137
+ wait-message = [M_WAIT, session-id, waiting-time]
138
+
139
+ message /= invalid-message
140
+ invalid-message = [M_INVALID, session-id, ?any]
141
+
142
+ noop-message = [M_NOOP]
143
+
144
+ divert-option = [O_DIVERT, +locator-option]
145
+
146
+ accept-option = [O_ACCEPT]
147
+
148
+ decline-option = [O_DECLINE, ?reason]
149
+ reason = text ; optional UTF-8 error message
150
+
151
+ waiting-time = 0..4294967295 ; in milliseconds
152
+ ttl = 0..4294967295 ; in milliseconds
153
+
154
+ locator-option /= [O_IPv4_LOCATOR, ipv4-address,
155
+ transport-proto, port-number]
156
+ ipv4-address = bytes .size 4
157
+
158
+ locator-option /= [O_IPv6_LOCATOR, ipv6-address,
159
+ transport-proto, port-number]
160
+ ipv6-address = bytes .size 16
161
+
162
+ locator-option /= [O_FQDN_LOCATOR, text, transport-proto,
163
+ port-number]
164
+
165
+ locator-option /= [O_URI_LOCATOR, text,
166
+ transport-proto / null, port-number / null]
167
+
168
+ transport-proto = IPPROTO_TCP / IPPROTO_UDP
169
+ IPPROTO_TCP = 6
170
+ IPPROTO_UDP = 17
171
+ port-number = 0..65535
172
+
173
+ initiator = ipv4-address / ipv6-address
174
+
175
+ objective-flags = uint .bits objective-flag
176
+
177
+ objective-flag = &(
178
+ F_DISC: 0 ; valid for discovery
179
+ F_NEG: 1 ; valid for negotiation
180
+ F_SYNCH: 2 ; valid for synchronization
181
+ F_NEG_DRY: 3 ; negotiation is a dry run
182
+ )
183
+
184
+ objective = [objective-name, objective-flags,
185
+ loop-count, ?objective-value]
186
+
187
+ objective-name = text ; see section "Format of Objective Options"
188
+
189
+ objective-value = any
190
+
191
+ loop-count = 0..255
192
+
193
+ ; Constants for message types and option types
194
+
195
+ M_NOOP = 0
196
+ M_DISCOVERY = 1
197
+ M_RESPONSE = 2
198
+ M_REQ_NEG = 3
199
+ M_REQ_SYN = 4
200
+ M_NEGOTIATE = 5
201
+ M_END = 6
202
+ M_WAIT = 7
203
+ M_SYNCH = 8
204
+ M_FLOOD = 9
205
+ M_INVALID = 99
206
+
207
+ O_DIVERT = 100
208
+ O_ACCEPT = 101
209
+ O_DECLINE = 102
210
+ O_IPv6_LOCATOR = 103
211
+ O_IPv4_LOCATOR = 104
212
+ O_FQDN_LOCATOR = 105
213
+ O_URI_LOCATOR = 106
data/lib/cddlc.rb CHANGED
@@ -1,4 +1,6 @@
1
1
  require_relative "parser/cddl-util.rb"
2
+ require_relative "processor/cddl-visitor.rb"
3
+ require_relative 'processor/cddl-undefined.rb'
2
4
 
3
5
  class CDDL
4
6
  @@parser = CDDLGRAMMARParser.new
@@ -22,7 +24,23 @@ class CDDL
22
24
  reason.join("\n")
23
25
  end
24
26
 
27
+ # (keeps only renamed rules)
28
+ def rename(rename_map)
29
+ rules.replace(
30
+ Hash[rename_map.map do |o, n|
31
+ [n, visit(rules[o]) do |prod|
32
+ case prod
33
+ in ["name", *] | ["gen", *]
34
+ prod[1] = rename_map[prod[1]] || prod[1]
35
+ else
36
+ end
37
+ false
38
+ end]
39
+ end])
40
+ end
41
+
25
42
  SAFE_FN = /\A[-._a-zA-Z0-9]+\z/
43
+ IMPINC = /\A(?:import|include)\z/
26
44
 
27
45
  def self.from_cddl(s)
28
46
  ast = @@parser.parse s
@@ -39,16 +57,10 @@ class CDDL
39
57
  ret.directives.each do |di|
40
58
  preferred_tag = nil
41
59
  case di
42
- in ["include" => dir, docref]
43
- in ["include" => dir, docref, "as", preferred_tag]
44
- warn "** Ignoring namespace tag #{preferred_tag} for now"
45
- in ["import" => dir, docref]
60
+ in [IMPINC => dir, SAFE_FN => docref]
61
+ in [IMPINC => dir, SAFE_FN => docref, "as", SAFE_FN => preferred_tag]
46
62
  else
47
- warn "** Can't parse include directive #{di.inspect}"
48
- next
49
- end
50
- unless docref =~ SAFE_FN
51
- warn "** skipping unsafe filename #{docref}"
63
+ warn "** Can't parse directive »#{di.join(" ")}«"
52
64
  next
53
65
  end
54
66
  puts "PREFERRED_TAG #{preferred_tag}" if $options.verbose
@@ -71,26 +83,39 @@ class CDDL
71
83
 
72
84
  include_file = io.read
73
85
  included_cddl = CDDL.from_cddl(include_file)
74
- # XXX: Should namespace that thing now! all names -> preferred_tag.name
75
- # p included_cddl.rules.keys
76
- # XXX: do once, first, to rename COSE_Key to RFC9052.COSE_Key
86
+ if preferred_tag
87
+ included_cddl = included_cddl.deep_clone # needed?
88
+ renamed_names = included_cddl.rules.keys
89
+ name_rename = Hash[
90
+ renamed_names.map { |o|
91
+ n = "#{preferred_tag}.#{o}"
92
+ warn "** Warning: renamed name #{n} already in #{fn}" if included_cddl.rules[n]
93
+ [o, n]}]
94
+ included_cddl.rename(name_rename)
95
+ end
96
+
77
97
  case dir
78
98
  in "import"
79
99
  warn "** IMPORTING #{fn}" if $options.verbose
80
- require_relative '../lib/processor/cddl-undefined.rb'
100
+ undef_rule = nil
81
101
  loop do
82
102
  undef_rule = ret.cddl_undefined # XXX square...
83
103
  # p undef_rule
84
104
  got_more = false
85
105
  undef_rule.each do |name|
86
106
  if rule = included_cddl.rules[name]
87
- ret.rules[name] = rule # XXX must be namespaced!
88
- warn "IMPORTED #{name} from #{fn}" if $options.verbose # ...: #{rule}...
107
+ ret.rules[name] = rule
108
+ warn "IMPORTED #{name} from #{fn}" if $options.verbose
89
109
  got_more = true
90
110
  end
91
111
  end
92
112
  break unless got_more
93
113
  end
114
+ if preferred_tag
115
+ undef_rule.each do |name|
116
+ warn "** Warning: undefined reference #{name} without namespace prefix is defined in namespaced imported module #{fn}" if name_rename[name]
117
+ end
118
+ end
94
119
  in "include"
95
120
  warn "** INCLUDING #{fn}" if $options.verbose
96
121
  included_cddl.rules.each do |k, v|
@@ -137,7 +162,6 @@ class CDDL
137
162
  fail unless name.size == 2
138
163
  name = name[1]
139
164
  when "gen"
140
- require_relative "processor/cddl-visitor.rb"
141
165
  parmnames = name[2..-1]
142
166
  name = name[1] # XXX update val with parm/arg
143
167
  val = ["parm", parmnames,
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cddlc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Carsten Bormann
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-02-06 00:00:00.000000000 Z
11
+ date: 2023-03-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -78,6 +78,7 @@ files:
78
78
  - data/prelude.cddl
79
79
  - data/rfc8727.cddl
80
80
  - data/rfc8927.cddl
81
+ - data/rfc8990-cleaned.cddl
81
82
  - data/rfc8990.cddl
82
83
  - data/rfc9052.cddl
83
84
  - data/rfc9053.cddl
@@ -122,7 +123,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
122
123
  - !ruby/object:Gem::Version
123
124
  version: '0'
124
125
  requirements: []
125
- rubygems_version: 3.4.2
126
+ rubygems_version: 3.4.6
126
127
  signing_key:
127
128
  specification_version: 4
128
129
  summary: CDDL (Concise Data Definition Language) converters and miscellaneous tools