genprovider 0.2.0
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.
- data/CHANGELOG +8 -0
- data/CHANGELOG~ +4 -0
- data/Gemfile +4 -0
- data/LICENSE +58 -0
- data/README.rdoc +50 -0
- data/Rakefile +6 -0
- data/bin/genprovider +256 -0
- data/bin/regprovider +105 -0
- data/features/003-create.feature +10 -0
- data/features/004-modify.feature +9 -0
- data/features/005-delete.feature +7 -0
- data/features/datatypes.feature +13 -0
- data/features/ensure-format.feature +28 -0
- data/features/have-instances.feature +19 -0
- data/features/mof/trivial.mof +20 -0
- data/features/registration.feature +12 -0
- data/features/run-genprovider.feature +10 -0
- data/features/show-context.feature +9 -0
- data/features/step_definitions/genprovider.rb +52 -0
- data/features/step_definitions/mof.rb +3 -0
- data/features/step_definitions/registration.rb +21 -0
- data/features/step_definitions/wbemcli.rb +58 -0
- data/features/support/env.rb +20 -0
- data/genprovider.gemspec +36 -0
- data/lib/genprovider/class.rb +200 -0
- data/lib/genprovider/classinfo.rb +88 -0
- data/lib/genprovider/output.rb +104 -0
- data/lib/genprovider/provider.rb +721 -0
- data/lib/genprovider/rdoc.rb +149 -0
- data/lib/genprovider/registration.rb +22 -0
- data/lib/genprovider/testcase.rb +139 -0
- data/lib/genprovider/version.rb +3 -0
- data/lib/genprovider.rb +35 -0
- data/samples/mof/LMI_Embedded.mof +6 -0
- data/samples/mof/RCP_ArrayDataTypes.mof +27 -0
- data/samples/mof/RCP_ClassMethod.mof +7 -0
- data/samples/mof/RCP_ComplexMethod.mof +14 -0
- data/samples/mof/RCP_IndicationGenerator.mof +13 -0
- data/samples/mof/RCP_PassCData.mof +10 -0
- data/samples/mof/RCP_ShowContext.mof +11 -0
- data/samples/mof/RCP_SimpleClass.mof +7 -0
- data/samples/mof/RCP_SimpleDataTypes.mof +27 -0
- data/samples/mof/RCP_SimpleMethod.mof +9 -0
- data/samples/mof/qualifiers.mof +20 -0
- data/samples/provider/lmi_embedded.rb +148 -0
- data/samples/provider/rcp_array_data_types.rb +219 -0
- data/samples/provider/rcp_class_method.rb +54 -0
- data/samples/provider/rcp_complex_method.rb +170 -0
- data/samples/provider/rcp_pass_c_data.rb +130 -0
- data/samples/provider/rcp_show_context.rb +134 -0
- data/samples/provider/rcp_simple_class.rb +124 -0
- data/samples/provider/rcp_simple_data_types.rb +152 -0
- data/samples/provider/rcp_simple_method.rb +143 -0
- data/samples/registration/LMI_Embedded.registration +7 -0
- data/samples/registration/RCP_ArrayDataTypes.registration +7 -0
- data/samples/registration/RCP_ClassMethod.registration +8 -0
- data/samples/registration/RCP_ComplexMethod.registration +8 -0
- data/samples/registration/RCP_PassCData.registration +7 -0
- data/samples/registration/RCP_ShowContext.registration +7 -0
- data/samples/registration/RCP_SimpleDataTypes.registration +7 -0
- data/samples/registration/RCP_SimpleMethod.registration +8 -0
- data/samples/sfcb.reg/RCP_ComputerSystem.reg +5 -0
- data/samples/sfcb.reg/RCP_OSProcess.reg +5 -0
- data/samples/sfcb.reg/RCP_OperatingSystem.reg +5 -0
- data/samples/sfcb.reg/RCP_PhysicalMemory.reg +5 -0
- data/samples/sfcb.reg/RCP_Processor.reg +5 -0
- data/samples/sfcb.reg/RCP_RunningOS.reg +5 -0
- data/samples/sfcb.reg/RCP_SimpleClass.reg +5 -0
- data/samples/sfcb.reg/RCP_UnixProcess.reg +5 -0
- data/sfcbd +4 -0
- data/stress.sh +4 -0
- data/tasks/clean.rake +4 -0
- data/tasks/doc.rake +16 -0
- data/tasks/features.rake +8 -0
- data/tasks/prepstage.rake +16 -0
- data/tasks/registration.rake +10 -0
- data/tasks/sfcb.rake +3 -0
- data/tasks/test.rake +10 -0
- data/test/env.rb +23 -0
- data/test/helper.rb +23 -0
- data/test/mkreg.rb +32 -0
- data/test/mof/RCP_ClassMethod.rb +15 -0
- data/test/mof/RCP_ComplexMethod.rb +16 -0
- data/test/mof/RCP_SimpleMethod.rb +15 -0
- data/test/registration.rb +37 -0
- data/test/sfcb.rb +94 -0
- data/test/test_lmi_embedded.rb +64 -0
- data/test/test_rcp_array_data_types.rb +140 -0
- data/test/test_rcp_class_method.rb +31 -0
- data/test/test_rcp_complex_method.rb +68 -0
- data/test/test_rcp_simple_data_types.rb +66 -0
- data/test/test_rcp_simple_method.rb +47 -0
- data/valgrind +8 -0
- metadata +288 -0
@@ -0,0 +1,721 @@
|
|
1
|
+
#
|
2
|
+
# provider.rb
|
3
|
+
#
|
4
|
+
|
5
|
+
class String
|
6
|
+
#
|
7
|
+
# Convert from CamelCase to under_score
|
8
|
+
#
|
9
|
+
def decamelize
|
10
|
+
self.gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
11
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
12
|
+
tr("-", "_").
|
13
|
+
downcase
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
require 'cim'
|
18
|
+
|
19
|
+
module CIM
|
20
|
+
class ReferenceType < Type
|
21
|
+
def to_cmpi
|
22
|
+
"Cmpi::ref"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
class Type
|
26
|
+
def to_cmpi
|
27
|
+
t = type
|
28
|
+
a = ""
|
29
|
+
if array?
|
30
|
+
a = "A"
|
31
|
+
end
|
32
|
+
"Cmpi::#{t}#{a}"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
class ClassFeature
|
36
|
+
def method_missing name
|
37
|
+
qualifiers[name]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
class Qualifier
|
41
|
+
def method_missing name, *args
|
42
|
+
if name == :"[]"
|
43
|
+
value[*args]
|
44
|
+
else
|
45
|
+
super name, *args
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
module Genprovider
|
53
|
+
class Provider
|
54
|
+
#
|
55
|
+
# iterate features
|
56
|
+
# **internal**
|
57
|
+
# predicate: feature predicate symbol, like :property?
|
58
|
+
# filter: :keys # keys only
|
59
|
+
# :nokeys # non-keys only
|
60
|
+
# :all # all
|
61
|
+
#
|
62
|
+
# yields { |feature, klass| } if block_given?
|
63
|
+
# returns Array of [feature,klass] pairs else
|
64
|
+
#
|
65
|
+
def features predicate, filter
|
66
|
+
result = nil
|
67
|
+
#
|
68
|
+
# We start to iterate features from the child class and
|
69
|
+
# climb up the parent chain
|
70
|
+
# overrides = { name => features }
|
71
|
+
# collects information about overridden features along
|
72
|
+
# the parent chain
|
73
|
+
overrides = {}
|
74
|
+
|
75
|
+
# climb up parent chain
|
76
|
+
klass = @klass
|
77
|
+
while klass
|
78
|
+
klass.features.each do |feature|
|
79
|
+
next unless feature.send(predicate)
|
80
|
+
|
81
|
+
# overriden in child class ?
|
82
|
+
f_override = overrides[feature.name]
|
83
|
+
if f_override # Y: f_override = overriding feature
|
84
|
+
# copy qualifiers from overridden to overriding feature
|
85
|
+
feature.qualifiers.each do |q|
|
86
|
+
unless f_override.qualifiers[q.name] # non-overridden qualifier
|
87
|
+
f_override.qualifiers << q
|
88
|
+
end
|
89
|
+
end
|
90
|
+
next # skip this feature
|
91
|
+
end
|
92
|
+
|
93
|
+
# does this feature override a parent feature ?
|
94
|
+
overrides[feature.name] = feature if feature.override
|
95
|
+
|
96
|
+
if feature.key?
|
97
|
+
next if filter == :nokeys
|
98
|
+
else
|
99
|
+
next if filter == :keys
|
100
|
+
end
|
101
|
+
if block_given?
|
102
|
+
yield feature, klass
|
103
|
+
else
|
104
|
+
result ||= Array.new
|
105
|
+
result << [feature,klass]
|
106
|
+
end
|
107
|
+
end
|
108
|
+
klass = klass.parent
|
109
|
+
end
|
110
|
+
result
|
111
|
+
end
|
112
|
+
|
113
|
+
# iterate properties
|
114
|
+
# filter: :keys # keys only
|
115
|
+
# :nokeys # non-keys only
|
116
|
+
# :all # all
|
117
|
+
#
|
118
|
+
# accepts optional block
|
119
|
+
#
|
120
|
+
def properties filter, &block
|
121
|
+
features :property?, filter, &block
|
122
|
+
end
|
123
|
+
|
124
|
+
# iterate methods
|
125
|
+
#
|
126
|
+
# accepts optional block
|
127
|
+
#
|
128
|
+
def methods &block
|
129
|
+
features :method?, :all, &block
|
130
|
+
end
|
131
|
+
|
132
|
+
LOG = "@trace_file.puts" # "@log.info"
|
133
|
+
|
134
|
+
#
|
135
|
+
# Find bounds for property values
|
136
|
+
#
|
137
|
+
# Usage:
|
138
|
+
# bounds property, :MaxLen, :Max, :Min
|
139
|
+
#
|
140
|
+
def bounds property, *args
|
141
|
+
s = ""
|
142
|
+
args.each do |n|
|
143
|
+
v = property.send(n)
|
144
|
+
s << "#{n} #{v} " if v
|
145
|
+
end
|
146
|
+
s
|
147
|
+
end
|
148
|
+
|
149
|
+
#
|
150
|
+
# Return reasonable default for type
|
151
|
+
#
|
152
|
+
def default_for_type type
|
153
|
+
if type.array? then "[]"
|
154
|
+
elsif type == :boolean then "false"
|
155
|
+
else "nil"
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
#
|
160
|
+
# generate line to set a property
|
161
|
+
# i.e. result.Property = nil # property_type + valuemap
|
162
|
+
#
|
163
|
+
def property_setter_line property, klass, result_name = "result"
|
164
|
+
valuemap = property.ValueMap
|
165
|
+
values = property.Values
|
166
|
+
type = property.type
|
167
|
+
if valuemap
|
168
|
+
firstval = values ? values[0] : valuemap[0]
|
169
|
+
if firstval.to_s =~ /\s/
|
170
|
+
firstval = "send(#{firstval.to_sym.inspect})"
|
171
|
+
end
|
172
|
+
default = "#{property.name}.#{firstval}"
|
173
|
+
default = "[#{default}]" if type.array?
|
174
|
+
else
|
175
|
+
default = default_for_type type
|
176
|
+
end
|
177
|
+
bounds = bounds property, :MaxLen, :Max, :Min
|
178
|
+
"#{result_name}.#{property.name} = #{default} # #{type} #{bounds} (-> #{klass.name})"
|
179
|
+
end
|
180
|
+
#
|
181
|
+
# Class#each
|
182
|
+
#
|
183
|
+
def mkeach
|
184
|
+
@out.puts "private"
|
185
|
+
@out.comment
|
186
|
+
@out.comment "Iterator for names and instances"
|
187
|
+
@out.comment " yields references matching reference and properties"
|
188
|
+
@out.comment
|
189
|
+
@out.def "each", "context", "reference", "properties = nil", "want_instance = false"
|
190
|
+
@out.puts "result = Cmpi::CMPIObjectPath.new reference.namespace, #{@klass.name.inspect}"
|
191
|
+
@out.puts("if want_instance").inc
|
192
|
+
@out.puts "result = Cmpi::CMPIInstance.new result"
|
193
|
+
@out.puts "result.set_property_filter(properties) if properties"
|
194
|
+
@out.end
|
195
|
+
@out.puts
|
196
|
+
@out.comment "Set key properties"
|
197
|
+
@out.puts
|
198
|
+
properties :keys do |prop, klass|
|
199
|
+
@out.puts(property_setter_line prop, klass)
|
200
|
+
end
|
201
|
+
@out.puts("unless want_instance").inc
|
202
|
+
@out.puts "yield result"
|
203
|
+
@out.puts "return"
|
204
|
+
@out.end
|
205
|
+
@out.puts
|
206
|
+
@out.comment "Instance: Set non-key properties"
|
207
|
+
@out.puts
|
208
|
+
properties :nokeys do |prop, klass|
|
209
|
+
deprecated = prop.deprecated
|
210
|
+
required = prop.required
|
211
|
+
if required
|
212
|
+
@out.comment "Required !"
|
213
|
+
@out.puts "#{property_setter_line prop, klass}"
|
214
|
+
else
|
215
|
+
@out.comment "Deprecated !" if deprecated
|
216
|
+
# using @out.comment would break the line at col 72
|
217
|
+
@out.puts "# #{property_setter_line prop, klass}"
|
218
|
+
end
|
219
|
+
end
|
220
|
+
@out.puts "yield result"
|
221
|
+
@out.end
|
222
|
+
@out.puts "public"
|
223
|
+
end
|
224
|
+
#
|
225
|
+
# Generate Class#initialize
|
226
|
+
#
|
227
|
+
def mknew
|
228
|
+
@out.comment
|
229
|
+
@out.comment "Provider initialization"
|
230
|
+
@out.comment
|
231
|
+
@out.def "initialize", "name", "broker", "context"
|
232
|
+
@out.puts "@trace_file = STDERR"
|
233
|
+
@out.puts "super broker"
|
234
|
+
@out.end
|
235
|
+
end
|
236
|
+
|
237
|
+
#
|
238
|
+
# Generate create_instance
|
239
|
+
#
|
240
|
+
def mkcreate
|
241
|
+
@out.def "create_instance", "context", "result", "reference", "newinst"
|
242
|
+
@out.puts "#{LOG} \"#{@name}.create_instance ref \#{reference}, newinst \#{newinst.inspect}\""
|
243
|
+
@out.comment "Create instance according to reference and newinst"
|
244
|
+
@out.puts "result.return_objectpath reference"
|
245
|
+
@out.puts "result.done"
|
246
|
+
@out.puts "true"
|
247
|
+
@out.end
|
248
|
+
end
|
249
|
+
|
250
|
+
#
|
251
|
+
# Generate enum_instance_names
|
252
|
+
#
|
253
|
+
def mkenum_instance_names
|
254
|
+
@out.def "enum_instance_names", "context", "result", "reference"
|
255
|
+
@out.puts "#{LOG} \"#{@name}.enum_instance_names ref \#{reference}\""
|
256
|
+
@out.puts("each(context, reference) do |ref|").inc
|
257
|
+
@out.puts "#{LOG} \"ref \#{ref}\""
|
258
|
+
@out.puts "result.return_objectpath ref"
|
259
|
+
@out.end
|
260
|
+
@out.puts "result.done"
|
261
|
+
@out.puts "true"
|
262
|
+
@out.end
|
263
|
+
end
|
264
|
+
|
265
|
+
#
|
266
|
+
# Generate enum_instances
|
267
|
+
#
|
268
|
+
def mkenum_instances
|
269
|
+
@out.def "enum_instances", "context", "result", "reference", "properties"
|
270
|
+
@out.puts "#{LOG} \"#{@name}.enum_instances ref \#{reference}, props \#{properties.inspect}\""
|
271
|
+
@out.puts("each(context, reference, properties, true) do |instance|").inc
|
272
|
+
@out.puts "#{LOG} \"instance \#{instance}\""
|
273
|
+
@out.puts "result.return_instance instance"
|
274
|
+
@out.end
|
275
|
+
@out.puts "result.done"
|
276
|
+
@out.puts "true"
|
277
|
+
@out.end
|
278
|
+
end
|
279
|
+
|
280
|
+
#
|
281
|
+
# Generate get_instance
|
282
|
+
#
|
283
|
+
def mkget_instance
|
284
|
+
@out.def "get_instance", "context", "result", "reference", "properties"
|
285
|
+
@out.puts "#{LOG} \"#{@name}.get_instance ref \#{reference}, props \#{properties.inspect}\""
|
286
|
+
@out.puts("each(context, reference, properties, true) do |instance|").inc
|
287
|
+
@out.puts "#{LOG} \"instance \#{instance}\""
|
288
|
+
@out.puts "result.return_instance instance"
|
289
|
+
@out.puts "break # only return first instance"
|
290
|
+
@out.end
|
291
|
+
@out.puts "result.done"
|
292
|
+
@out.puts "true"
|
293
|
+
@out.end
|
294
|
+
end
|
295
|
+
|
296
|
+
#
|
297
|
+
# Generate set_instance
|
298
|
+
#
|
299
|
+
def mkset_instance
|
300
|
+
@out.def "set_instance", "context", "result", "reference", "newinst", "properties"
|
301
|
+
@out.puts "#{LOG} \"#{@name}.set_instance ref \#{reference}, newinst \#{newinst.inspect}, props \#{properties.inspect}\""
|
302
|
+
@out.puts("properties.each do |prop|").inc
|
303
|
+
@out.puts "newinst.send \"\#{prop.name}=\".to_sym, FIXME"
|
304
|
+
@out.end
|
305
|
+
@out.puts "result.return_instance newinst"
|
306
|
+
@out.puts "result.done"
|
307
|
+
@out.puts "true"
|
308
|
+
@out.end
|
309
|
+
end
|
310
|
+
|
311
|
+
#
|
312
|
+
# Generate delete_instance
|
313
|
+
#
|
314
|
+
def mkdelete_instance
|
315
|
+
@out.def "delete_instance", "context", "result", "reference"
|
316
|
+
@out.puts "#{LOG} \"#{@name}.delete_instance ref \#{reference}\""
|
317
|
+
@out.puts "result.done"
|
318
|
+
@out.puts "true"
|
319
|
+
@out.end
|
320
|
+
end
|
321
|
+
|
322
|
+
#
|
323
|
+
# Generate exec_query
|
324
|
+
#
|
325
|
+
def mkquery
|
326
|
+
@out.comment "query : String"
|
327
|
+
@out.comment "lang : String"
|
328
|
+
@out.def "exec_query", "context", "result", "reference", "query", "lang"
|
329
|
+
@out.puts "#{LOG} \"#{@name}.exec_query ref \#{reference}, query \#{query}, lang \#{lang}\""
|
330
|
+
@out.printf "keys = ["
|
331
|
+
first = true
|
332
|
+
properties :keys do |property, klass|
|
333
|
+
@out.write ", " unless first
|
334
|
+
first = false
|
335
|
+
@out.write "\"#{property.name}\""
|
336
|
+
end
|
337
|
+
@out.puts "]"
|
338
|
+
@out.puts "expr = CMPISelectExp.new query, lang, keys"
|
339
|
+
@out.puts("each(context, reference, expr.filter, true) do |instance|").inc
|
340
|
+
@out.puts( "if expr.match(instance)").inc
|
341
|
+
@out.puts "result.return_instance instance"
|
342
|
+
@out.end
|
343
|
+
@out.end
|
344
|
+
@out.puts "result.done"
|
345
|
+
@out.puts "true"
|
346
|
+
@out.end
|
347
|
+
end
|
348
|
+
|
349
|
+
#
|
350
|
+
# Generate cleanup
|
351
|
+
#
|
352
|
+
def mkcleanup
|
353
|
+
@out.def "cleanup", "context", "terminating"
|
354
|
+
@out.puts "#{LOG} \"#{@name}.cleanup terminating? \#{terminating}\""
|
355
|
+
@out.puts "true"
|
356
|
+
@out.end
|
357
|
+
end
|
358
|
+
|
359
|
+
def mktypemap
|
360
|
+
@out.def("self.typemap")
|
361
|
+
@out.puts("{").inc
|
362
|
+
properties :all do |property, klass|
|
363
|
+
t = property.type
|
364
|
+
s = t.to_cmpi
|
365
|
+
if t == CIM::ReferenceType
|
366
|
+
# use t.name to stay Ruby-compatible. t.to_s would print MOF syntax
|
367
|
+
@out.comment t.to_s
|
368
|
+
elsif t == :string # check for Embedded{Instance,Object}
|
369
|
+
if property.embeddedinstance?
|
370
|
+
s = "Cmpi::embedded_instance"
|
371
|
+
elsif property.embeddedobject?
|
372
|
+
s = "Cmpi::embedded_object"
|
373
|
+
end
|
374
|
+
elsif t == :stringA # check for Embedded{Instance,Object}
|
375
|
+
if property.embeddedinstance?
|
376
|
+
s = "Cmpi::embedded_instanceA"
|
377
|
+
elsif property.embeddedobject?
|
378
|
+
s = "Cmpi::embedded_objectA"
|
379
|
+
end
|
380
|
+
end
|
381
|
+
@out.puts "#{property.name.inspect} => #{s},"
|
382
|
+
end
|
383
|
+
@out.dec.puts "}"
|
384
|
+
@out.end
|
385
|
+
end
|
386
|
+
|
387
|
+
def make_valuemap_header
|
388
|
+
return if @valuemap_headers_done
|
389
|
+
@out.comment
|
390
|
+
@out.comment "----------------- valuemaps following, don't touch -----------------"
|
391
|
+
@out.comment
|
392
|
+
@valuemap_headers_done = true
|
393
|
+
end
|
394
|
+
#
|
395
|
+
# make_valuemap
|
396
|
+
# make one ValueMap class
|
397
|
+
#
|
398
|
+
def make_valuemap property
|
399
|
+
t = property.type
|
400
|
+
# get the Values and ValueMap qualifiers
|
401
|
+
valuemap = property.ValueMap
|
402
|
+
return unless valuemap
|
403
|
+
make_valuemap_header
|
404
|
+
values = property.Values
|
405
|
+
@out.puts
|
406
|
+
@out.puts("class #{property.name} < Cmpi::ValueMap").inc
|
407
|
+
@out.def "self.map"
|
408
|
+
@out.puts("{").inc
|
409
|
+
# get to the array
|
410
|
+
valuemap = valuemap
|
411
|
+
# values might be nil, then only ValueMap given
|
412
|
+
if values
|
413
|
+
values = values
|
414
|
+
elsif !t.matches?(String)
|
415
|
+
raise "ValueMap missing Values for property #{property.name} with non-string type #{t}"
|
416
|
+
end
|
417
|
+
loop do
|
418
|
+
val = values.shift if values
|
419
|
+
map = valuemap.shift
|
420
|
+
if val.nil? && values
|
421
|
+
# have values but its empty
|
422
|
+
break unless map # ok, both nil
|
423
|
+
raise "#{property.name}: Values empty, ValueMap #{map}"
|
424
|
+
end
|
425
|
+
unless map
|
426
|
+
break unless val # ok, both nil
|
427
|
+
raise "#{property.name}: Values #{val}, ValueMap empty"
|
428
|
+
end
|
429
|
+
if val
|
430
|
+
if map =~ /\.\./
|
431
|
+
@out.comment "#{val.inspect} => #{map},"
|
432
|
+
else
|
433
|
+
@out.puts "#{val.inspect} => #{map},"
|
434
|
+
end
|
435
|
+
else
|
436
|
+
@out.puts "#{map.inspect} => #{map.to_sym.inspect},"
|
437
|
+
end
|
438
|
+
end
|
439
|
+
@out.dec.puts "}"
|
440
|
+
@out.end
|
441
|
+
@out.end
|
442
|
+
end
|
443
|
+
|
444
|
+
#
|
445
|
+
# Generate valuemap classes
|
446
|
+
#
|
447
|
+
def mkvaluemaps
|
448
|
+
properties :all do |property, klass|
|
449
|
+
make_valuemap property
|
450
|
+
end
|
451
|
+
methods do |method, klass|
|
452
|
+
make_valuemap method
|
453
|
+
end
|
454
|
+
end
|
455
|
+
|
456
|
+
# base instance callbacks
|
457
|
+
# use by association and instance providers
|
458
|
+
def mkbaseinstance
|
459
|
+
mkeach
|
460
|
+
@out.puts
|
461
|
+
mkenum_instance_names
|
462
|
+
@out.puts
|
463
|
+
mkenum_instances
|
464
|
+
@out.puts
|
465
|
+
mkget_instance
|
466
|
+
@out.puts
|
467
|
+
end
|
468
|
+
|
469
|
+
def mkinstance
|
470
|
+
mkbaseinstance
|
471
|
+
mkcreate
|
472
|
+
@out.puts
|
473
|
+
mkset_instance
|
474
|
+
@out.puts
|
475
|
+
mkdelete_instance
|
476
|
+
@out.puts
|
477
|
+
mkquery
|
478
|
+
end
|
479
|
+
|
480
|
+
def mkargs args, name
|
481
|
+
s = ""
|
482
|
+
args.each do |arg|
|
483
|
+
s << ", " unless s.empty?
|
484
|
+
s << arg.name.inspect
|
485
|
+
s << ", #{arg.type.to_cmpi}"
|
486
|
+
end
|
487
|
+
s
|
488
|
+
end
|
489
|
+
|
490
|
+
def explain_args args, text
|
491
|
+
@out.comment "#{text} args"
|
492
|
+
if args.empty?
|
493
|
+
@out.comment " - none -"
|
494
|
+
end
|
495
|
+
args.each do |arg|
|
496
|
+
@out.comment "#{arg.name} : #{arg.type}", 1
|
497
|
+
d = arg.description
|
498
|
+
@out.comment("#{d}", 3) if d
|
499
|
+
valuemap = arg.valuemap
|
500
|
+
# values might be nil, then only ValueMap given
|
501
|
+
if valuemap
|
502
|
+
@out.comment "Value can be one of", 3
|
503
|
+
valuemap = valuemap
|
504
|
+
values = arg.values
|
505
|
+
if values
|
506
|
+
values = values
|
507
|
+
loop do
|
508
|
+
s = values.shift
|
509
|
+
v = valuemap.shift
|
510
|
+
break unless v && s
|
511
|
+
@out.comment "#{s}: #{v}", 5
|
512
|
+
end
|
513
|
+
else
|
514
|
+
valuemap.each do |v|
|
515
|
+
@out.comment v, 5
|
516
|
+
end
|
517
|
+
end
|
518
|
+
end
|
519
|
+
end
|
520
|
+
@out.comment
|
521
|
+
end
|
522
|
+
|
523
|
+
def mkmethods
|
524
|
+
@out.comment "Methods"
|
525
|
+
@out.puts
|
526
|
+
methods do |method, klass|
|
527
|
+
next if method.deprecated
|
528
|
+
@out.comment "#{klass.name}: #{method.type} #{method.name}(...)"
|
529
|
+
@out.comment
|
530
|
+
input = []
|
531
|
+
output = []
|
532
|
+
method.parameters.each do |p|
|
533
|
+
input << p if p.in?
|
534
|
+
output << p if p.out?
|
535
|
+
STDERR.puts "#{p.name} is IN and OUT" if p.in? && p.out?
|
536
|
+
STDERR.puts "#{p.name} is neither IN nor OUT" unless p.in? || p.out?
|
537
|
+
end
|
538
|
+
name = method.name
|
539
|
+
decam = name.decamelize
|
540
|
+
# type and argument information
|
541
|
+
# must be array since order here is order of args passed to function
|
542
|
+
# first element is list of input args (alternating name and type)
|
543
|
+
# second is list of output args (starting with return type, then name and type of additional out args)
|
544
|
+
# -> used by cmpi_bindings !
|
545
|
+
@out.comment "type information for #{name}(...)"
|
546
|
+
@out.puts "def #{decam}_args; [[#{mkargs(input, decam)}],[#{method.type.to_cmpi}, #{mkargs(output, decam)}]] end"
|
547
|
+
@out.comment
|
548
|
+
d = method.description.value rescue nil
|
549
|
+
if d
|
550
|
+
@out.comment "#{d}"
|
551
|
+
@out.comment
|
552
|
+
end
|
553
|
+
v = method.values
|
554
|
+
default_return_value = default_for_type method.type
|
555
|
+
if v
|
556
|
+
@out.comment "See class #{method.name} for return values"
|
557
|
+
@out.comment
|
558
|
+
firstval = v[0]
|
559
|
+
if firstval.to_s =~ /\s/
|
560
|
+
firstval = "send(#{firstval.to_sym.inspect})"
|
561
|
+
end
|
562
|
+
default_return_value = "#{name}.#{firstval}"
|
563
|
+
end
|
564
|
+
explain_args input, "Input"
|
565
|
+
explain_args output, "Additional output"
|
566
|
+
args = ["#{decam}", "context", "reference"]
|
567
|
+
method.parameters.each do |arg|
|
568
|
+
args << arg.name.decamelize
|
569
|
+
end
|
570
|
+
@out.def *args
|
571
|
+
args.shift
|
572
|
+
log = ""
|
573
|
+
args.each do |arg|
|
574
|
+
log << ", " unless log.empty?
|
575
|
+
log << "\#{#{arg}}"
|
576
|
+
end
|
577
|
+
@out.puts "#{LOG} \"#{decam} #{log}\""
|
578
|
+
|
579
|
+
# Empty arrays are not transferred by sfcc/cimxml, end up as nil
|
580
|
+
input.each do |arg|
|
581
|
+
next unless arg.type.array?
|
582
|
+
@out.puts "#{arg.name.decamelize} ||= []"
|
583
|
+
end
|
584
|
+
|
585
|
+
args = [ "method_return_value" ]
|
586
|
+
@out.puts "method_return_value = #{default_return_value} # #{method.type}"
|
587
|
+
if output.size > 0
|
588
|
+
@out.puts
|
589
|
+
@out.comment "Output arguments"
|
590
|
+
output.each do |arg|
|
591
|
+
name = arg.name.decamelize
|
592
|
+
@out.puts "#{name} = nil # #{arg.type}"
|
593
|
+
args << name
|
594
|
+
end
|
595
|
+
end
|
596
|
+
@out.puts
|
597
|
+
@out.comment " function body goes here"
|
598
|
+
@out.puts
|
599
|
+
if args.size > 1
|
600
|
+
@out.puts "return [#{args.join(', ')}]"
|
601
|
+
else
|
602
|
+
@out.puts "return #{args[0]}"
|
603
|
+
end
|
604
|
+
@out.end
|
605
|
+
@out.puts
|
606
|
+
end
|
607
|
+
|
608
|
+
# @out.puts
|
609
|
+
# @out.def "invoke_method", "context", "result", "reference", "method", "argsin", "argsout"
|
610
|
+
# @out.puts "#{LOG} \"invoke_method \#{context}, \#{result}, \#{reference}, \#{method}, \#{argsin}, \#{argsout}\""
|
611
|
+
# @out.end
|
612
|
+
end
|
613
|
+
|
614
|
+
def mkassociations
|
615
|
+
@out.comment "Associations"
|
616
|
+
@out.def "associator_names", "context", "result", "reference", "assoc_class", "result_class", "role", "result_role"
|
617
|
+
@out.puts "#{LOG} \"#{@name}.associator_names \#{context}, \#{result}, \#{reference}, \#{assoc_class}, \#{result_class}, \#{role}, \#{result_role}\""
|
618
|
+
@out.end
|
619
|
+
@out.puts
|
620
|
+
@out.def "associators", "context", "result", "reference", "assoc_class", "result_class", "role", "result_role", "properties"
|
621
|
+
@out.puts "#{LOG} \"#{@name}.associators \#{context}, \#{result}, \#{reference}, \#{assoc_class}, \#{result_class}, \#{role}, \#{result_role}, \#{properties}\""
|
622
|
+
@out.end
|
623
|
+
@out.puts
|
624
|
+
@out.def "reference_names", "context", "result", "reference", "result_class", "role"
|
625
|
+
@out.puts "#{LOG} \"#{@name}.reference_names \#{context}, \#{result}, \#{reference}, \#{result_class}, \#{role}\""
|
626
|
+
@out.end
|
627
|
+
@out.puts
|
628
|
+
@out.def "references", "context", "result", "reference", "result_class", "role", "properties"
|
629
|
+
@out.puts "#{LOG} \"#{@name}.references \#{context}, \#{result}, \#{reference}, \#{result_class}, \#{role}, \#{properties}\""
|
630
|
+
@out.end
|
631
|
+
|
632
|
+
end
|
633
|
+
|
634
|
+
def mkindications
|
635
|
+
@out.comment "Indications"
|
636
|
+
end
|
637
|
+
|
638
|
+
def providertypes
|
639
|
+
mask = Genprovider.classmask @klass
|
640
|
+
res = []
|
641
|
+
res << "MethodProvider" if (mask & METHOD_MASK) != 0
|
642
|
+
res << "AssociationProvider" if (mask & ASSOCIATION_MASK) != 0
|
643
|
+
res << "IndicationProvider" if (mask & INDICATION_MASK) != 0
|
644
|
+
res << "InstanceProvider" if (mask & INSTANCE_MASK) != 0
|
645
|
+
|
646
|
+
[res, mask]
|
647
|
+
end
|
648
|
+
|
649
|
+
#
|
650
|
+
# generate provider code for class 'c'
|
651
|
+
#
|
652
|
+
# returns providername
|
653
|
+
#
|
654
|
+
|
655
|
+
def initialize c, name, out
|
656
|
+
@klass = c
|
657
|
+
@out = out
|
658
|
+
|
659
|
+
if name[0,1] == name[0,1].downcase
|
660
|
+
raise "Provider name (#{name}) must start with upper case"
|
661
|
+
end
|
662
|
+
@name = name
|
663
|
+
|
664
|
+
#
|
665
|
+
# Header: class name, provider name (Class qualifier 'provider')
|
666
|
+
#
|
667
|
+
|
668
|
+
@out.comment
|
669
|
+
@out.comment "Provider #{name} for class #{@klass.name}:#{@klass.class}"
|
670
|
+
@out.comment
|
671
|
+
|
672
|
+
@out.puts("require 'syslog'").puts
|
673
|
+
@out.puts("require 'cmpi/provider'").puts
|
674
|
+
@out.puts("module Cmpi").inc
|
675
|
+
|
676
|
+
Genprovider::Class.mkdescription @out, @klass
|
677
|
+
if @klass.parent
|
678
|
+
Genprovider::Class.mkdescription @out, @klass.parent
|
679
|
+
end
|
680
|
+
p,mask = providertypes
|
681
|
+
|
682
|
+
@out.puts("class #{name} < #{p.shift}").inc
|
683
|
+
|
684
|
+
@out.puts
|
685
|
+
p.each do |t|
|
686
|
+
@out.puts "include #{t}IF"
|
687
|
+
end
|
688
|
+
mknew
|
689
|
+
@out.puts
|
690
|
+
mkcleanup
|
691
|
+
@out.puts
|
692
|
+
mktypemap
|
693
|
+
@out.puts
|
694
|
+
if (mask & METHOD_MASK) != 0
|
695
|
+
STDERR.puts " Generating Method provider"
|
696
|
+
mkmethods
|
697
|
+
@out.puts
|
698
|
+
end
|
699
|
+
if (mask & ASSOCIATION_MASK) != 0
|
700
|
+
STDERR.puts " Generating Association provider"
|
701
|
+
mkbaseinstance
|
702
|
+
mkassociations
|
703
|
+
end
|
704
|
+
if (mask & INDICATION_MASK) != 0
|
705
|
+
STDERR.puts " Generating Indication provider"
|
706
|
+
mkindications
|
707
|
+
@out.puts
|
708
|
+
end
|
709
|
+
if (mask & INSTANCE_MASK) != 0
|
710
|
+
STDERR.puts " Generating Instance provider"
|
711
|
+
mkinstance
|
712
|
+
@out.puts
|
713
|
+
end
|
714
|
+
|
715
|
+
mkvaluemaps
|
716
|
+
@out.end # class
|
717
|
+
@out.end # module
|
718
|
+
end
|
719
|
+
end
|
720
|
+
end
|
721
|
+
|